A Collection of Exercises for Learning Erlang (Or Any Other Language)

If you want to become an expert as a programmer you must deliberately practice programming. We can't hope to get better with our languages, our tools, or our general knowledge of programming such as algorithms, data structures and even general problem solving skills without putting some real effort into improving with them. Steve Yeggee put it well in his essay on practicing programming;

Contrary to what you might believe, merely doing your job every day doesn't qualify as real practice. Going to meetings isn't practicing your people skills, and replying to mail isn't practicing your typing. You have to set aside some time once in a while and do focused practice in order to get better at something.

The best way to get the aforementioned deliberative practice is to sit down and write some code. Solve a problem, solve it again, and if you want to add another performance metric then time yourself how long it takes you to solve it. Make sure the problem is challenging, maybe just outside your reach. Maybe you'll have to do some research before you solve it because you're unfamiliar with the problem domain, or some math involved. I've compiled a list of exercises that you can use to practice your programming skills. Despite the fact that this article's title is focused on erlang I have kept the problem set language agnostic to increase its usefulness.

Katas And Problems / Challenges

  • Code Kata - Prag Dave, who coined the term according to Wikipedia, has a collection of 21 (at the time of writing) katas for you to practice using whatever language you choose.
  • Project Euler - A collection of hundreds mathematical problems not branded as Katas, but will nonehteless get you writing code. The problems are designed to be solved programmatically using any language you choose. As an added bonus these will get you doing some reading on mathematical topics too.
  • Roy Osherove's TDD Katas - A collection (of two at the time of writing) katas to get you started with test driven development. If you want to explore TDD further, the previously mentioned Project Euler kats can be used to practice TDD as well.
  • CodeDojo Kata Catalogue - A collection of Kata exercises that have been tried at Dojo meetings. They are broken down into five categories; Algorithmic, Game Modeling, Math Oriented, String Manipulation, Specific Technologies.
  • Programming Challenges [PDF Link] - The Programming Contest Training Manual for ACM competitions. This book not only offers challenges but teaches the topics as well. They apply to general computing focusing on data structures and algorithms.

General Learning Exercises

My Own Technique - Textbook Algorithms

I personally find a lot of value implementing algorithms from texts or practical books. This has the advantage of allowing you to practice a language, and gain a deeper insight into a specific topic. I've been eyeballing a text I used for an AI and Advanced AI course at University; Artificial Intelligence A Modern Approach by Stuart Russell and Peter Norvig as a potential candidate for this. The official site lists sources in Java, Python and Lisp and I think it would benefit me greatly to implement all of their code listings in Erlang.

If a thick technical text like this appears daunting to you, and it does it me thats why I haven't started, then perhaps you can try one of the many great practical books from publishers like Oreilly and Pragmatic Programmers, to name a few.

Share Your Own

This list was by no means exhaustive, and I'm sure you've got your own practice exercises that you like to use. I'd love to hear about the ones I've missed, and I hope I can fill in the gap in my practice regimen. Please share your own exercise sets or practice regimens in the comments below. I'll add them to this list, with attribution of course. :)

Reader Suggestion - Simple Web Server

parley left a great suggestion in the Hacker News Comments for this post;

Personally, I've always liked creating a simple web server as a nice step in learning a language/stdlib. Some concurrency, some I/O, some string parsing, etc. Obviously it's not the first thing one does, but I find it a nice package to put together that actually achieves something real.

If you liked this please consider sharing it on Hacker News or reddit.

Posted on 08 January 2012.

Erlang TDD - String Calculator Kata

Here is a quick video of me performing the String Calculator TDD Kata in just over ten minutes. As programmers we can use Kata's to artificially gain experience solving real problems. Katas can be used to learn a new language such as Erlang or a new technique such as TDD/BDD. For those who don't know, wikipedia defines a code kata as follows;

...a term coined by Dave Thomas, co-author of the book The Pragmatic Programmer, in a bow to the Japanese concept of kata in the martial arts. A code kata is an exercise in programming which helps a programmer hone their skills through practice and repetition.

I use vim, make, erlang and eunit to write a solution for the kata, up until the end of point five listed on the kata page linked above. If you'd like to learn how to configure vim or write a makefile to do this you can check out my article on Setting up Vim for Erlang TDD and Creating an Erlang Test Runner Using Make.

Erlang String Calculator TDD Kata from Cody Rioux on Vimeo.

I highly encourage you to give some katas a try to improve your programming skills. Next week I'll be posting a collection of Katas that you can use you familiarize yourself with new programming languages or techniques.

Posted on 01 January 2012.

Erlang TDD - Creating a Simple Erlang Test Runner

When you're doing Test Driven Development (TDD) it is necessary to be able to run your tests fast, and run your tests often. It's a major pain to even have to leave your editor to run the tests. I use MacVim for Erlang TDD with a split view and the last thing I want to do is take my hands off the keyboard to run a test. If you're new to erlang and/or the make utility then you might not know how to do this.

The Makefile

I'll setup a Makefile that will allow me to test the calc module I'll be making in the upcoming string calculator kata article I'll be writing. I've seen people use other tools such as rake for this, but make make is the standard according to Erlang's documentation. Vim also has excellent support for running make files from within the editor, we can simply type ":make test" right in vim to run the tests for the module I am currently working on. Assume we have two modules:

  • calc - A calculator module.
  • calc_tests - An EUnit test module containing tests for calc.

The first few lines tell make how to build our files. We'll tell make how to run erlang and store that in a variable called ERL using "ERL = erl -boot start_clean". We could call this variable anything we like. We then specify which files we are working with using the "MODS = ..." line. We're concerned with our current module and its test module. Again we can name this variable anything we'd like.

Now that we've got everything set up we can specify a few targets for make. Note that the first target is the default if you run make without any arguments. A target is specified using the following format:

target: dependencies
  actions

Note the formatting, including the necessary tab on the second line. All dependencies are executed before the actions code is run. If you take a look above our "make all" just compiles everything. Our "compile" simply converts all our mods to .beam (We told make how to do this at the top of the file.) Test depends on compile, so in order to run the tests make will rebuild the source files, this makes sense since we're constantly adding new tests and refactoring. Once compile is done executing, make will execute the line below which is crafted to run our unit tests.

test: compile
  ${ERL} -pa ./ -s eunit test calc -s init stop

Our test target depends on the compile target and simply runs eunit:test(calc) for us. This allows us to quickly test this module and view the results by typing "make test" from the command line or vim.

Scaling Up For Multiple Test Files

This works well when we are TTDing a single module, but what about an entire application? It doesn't really make sense to execute a bunch of different test modules like this, because you get a summary output per test file. It turns out that rebar has some decent facilities for running multiple tests. I'll write an article on that in the future when I investigate it further.

Posted on 30 December 2011.

Setting up VIM for Erlang TDD

While emacs might be the preferred editor for erlang code, I'm a vim junkie to the core and couldn't imagine changing my editor for a single language. If you're using vim to develop for erlang as well then these steps will help you smoothen the process of using vim for test driven development with erlang. In case you need anything from my vim configuration I host my personal vim setup on github so I can access it everywhere, and I encourage you to do the same!

I'm going to assume you already have your own vim setup, including a way to manage plugins such as pathogen and preferably a version controlled .vim directory so that you can use git submodules along with pathogen. If for some reason you don't then I recommend setting one up before continuing, there is a great screencast on Synchronizing plugins with git submodules and pathogen over at vimcasts.org. Its less than 10 minutes long and if you're a vim user you'll be happy you did it!

This article is not an introduction to EUnit. If you require an introduction to EUnit I will refer you to EUnited Nations Council from Learn You Some Erlang and Erlang Manual Chapter on EUnit. Both of those resources are free and will get you on your feet when it comes to writing unit tests for erlang. Now lets get vim setup...

The vimerl Plugin

The first thing we'll want is some erlang specific vim functionality. Thankfully there is a fantastic plugin called vimerl that encapsulates all of the erlang functionality we need. If you've followed the vimcasts.org screencast above you can install this plugin by typing the following command when in your .vim directory:

git submodule add https://github.com/jimenezrick/vimerl.git bundle/vimerl
git submodule init

This plugin enables several useful features including syntax highlighting, code folding, code completion, auto-indent, quickfix, and wrangler support.

Autocomplete

There is a gotcha with auto complete, you need to set the location of the erlang man pages in your .vimrc file. The issue is that the vimerl site lists this option as g:erlangManPath but in reality the variable has changed in vimerl to be named g:erlang_man_path. I used the command locate erlang at the command line to determine that my man pages were located at /usr/local/share/man/man3/ turns out that the plugin looks for the man3 directory so to set your vimrc up just add this line:

let g:erlang_man_path='/usr/local/share/man'

Keep in mind that the path will be different on your machine! This is for a machine running Mac OS X Lion and I used homebrew to install erlang. Once you have this setup you should be able to activate library autocompletion using Ctrl+X Ctrl+O.

Code Folding

You can setup vim to toggle folds with the spacebar by adding the following two lines to your .vimrc

nnoremap   @=(foldlevel('.')?'za':'l')
vnoremap  zf

Now just place the cursor on the body of a multi-line erlang function and hit the space bar. Vim will fold it all into one line.

Refactoring

There are a few refactoring commands that come with this package, and they really come in handy for the refactor part of red-green-refactor. They can extract a new function, rename a variable/function/module, and convert a function's arguments into a tuple. The trick to remembering the keys is that all the refactorings start with followed by a letter representing the change. See the list below:

  • Extract to a new function: Highlight code and press Alt-r e
  • Rename a variable: Put the cursor on it and press Alt-r v
  • Rename a function: Put the cursor on it and press Alt-r f
  • Rename a module: Press Alt-r m anywhere in the module
  • Convert arguments to tuples: Highlight arguments and press Alt-r t

As it turns out the refactoring support was removed from the latest, and currently maintained version of vimerl. Perhaps that could be a little project for someone (maybe me?) to learn how to write vim plugins at some point and re-add refactoring support to vimerl.

EUnit Snippets

When you're doing TDD its handy to have some snippets to help you get all your boilerplate testing code into the file quickly. So with that in mind head over to the snipMate Vim plugin page. Remember to add it properly if you're using git submodules to manage your vim plugins.

Now regardless of whether or not you installed snipMate as a submodule you will need to edit these snippets in the ~/.vim/snippets/erlang.snippets file. The neat part is that even though a bundle/snipMate/snippets/erlang.snippets file exists if you included snipMate as a submodule, it will still read snippets from all locations. This allows you to store your own changes without messing with the submodule. Let's add the following snippets for now:

# Include EUnit
snippet ince
	-include_lib("eunit/include/eunit.hrl"). 
# Assert
snippet ?
	?assert(${1:expression})
# Assert Not
snippet ?not
	?assertNot(${1:expression})
# Assert Equal
snippet ?equal
	?assertEqual(${1:expected}, ${2:actual})
# Assert Match
snippet ?match
	?assertMatch(${1:pattern}, ${2:expression})
# Assert Error
snippet ?error
	?assertError(${1:pattern}, ${2:expression})
# Assert Generator
snippet ?_
	?_assert(${1:expression})
# Assert Not Generator
snippet ?_not
	?_assertNot(${1:expression})
# Assert Equal Generator
snippet ?_equal
	?_assertEqual(${2:expected}, ${3:actual})
# Assert Match Generator
snippet ?_match
	?_assertMatch(${1:pattern}, ${2:expression})
# Assert Error Generator
snippet ?_error
	?_assertError(${1:pattern}, ${2:expression})
# Test Method Template
snippet test
	${1:unit}_${2:scenario}_${3:expectedResult}_test() ->
		?assert${4:assertion}(${5:expected}, ${6:actual}).
# Test Fixture
snippet fixture
	{${1:setup}, ${2:Where}, ${3:Setup}, ${4:Cleanup}, ${5:Instantiator}}

Wrap Up

Thats it, we now have a vim environment that supports autocomplete, code folding and refactoring for our language of choice. On top of that we have some snippets to help us write test cases with less keystrokes. Next Sunday we'll write a test runner and test out an existing Project Euler solution. Later on we'll take a look at using TDD to solve more Project Euler problems. Until then Happy Coding.

Posted on 23 December 2011.

Solving Project Euler Using Erlang - Problem Seven

I've been trying to work with erlang every day for a while now. I'm very keen on the language and its uses as well as finally becoming intimately familiar with a functional language. I have some plans in the future to release some machine learning and artificial intelligence code in erlang in hopes of continuing to increase my proficiency with it. Along with that I've been doing a ton of work with Javascript for a project that I cannot yet discuss, but will when it gets revealed.

I've also been supplementing my reading with Learn You Some Erlang For Great Good which covers a few topics that Programming Erlang: Software for a Concurrent World doesn't. I've really got to start keeping an eye out for free learning material before I go out and buy books all the time.

Problem Seven

By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13. What is the 10 001st prime number?

We've already solved the issue of finding a prime number back in problem three. So this is just a matter of writing a driver function that will recurse until its found the 10001st prime.

The solution is simple. We just need a recursive function that takes the prime count we're looking for, a current candidate, and the count of primes we've found. It will call itself recursively incrementing the candidate, and incrementing PrimeCount if the current candidate is a prime. It all looks like this put together:

The Code

Keep in mind the is_prime function is reused from problem three. You could also probabilistically determine primes if you're looking for a performance gain.

-module(problem7).
-export([start/0]).

start() ->
  find_xth_prime(10001).

find_xth_prime(X) ->
  find_xth_prime(X, 2, 1).

find_xth_prime(X, CurrentVal, PrimeCount) ->
  IsPrime = is_prime(CurrentVal),
  if IsPrime, PrimeCount + 1 =:= X ->
      {CurrentVal, PrimeCount};
    IsPrime, PrimeCount < X ->
      find_xth_prime(X, CurrentVal + 1, PrimeCount + 1);
    true ->
      find_xth_prime(X, CurrentVal + 1, PrimeCount)
  end.

is_prime(X) -> is_prime(X, 2).
is_prime(X, Divisor) -> 
  (if
    (X rem Divisor =:= 0) ->
      false;
   (Divisor >= X div 2) ->
     true;
   true ->
      is_prime(X, Divisor + 1)
 end).

Running problem7:start() outputs our answer.

Posted on 22 November 2011.