A nice habit that I picked up from the Pragmatic Programmer long ago was the excellent idea to commit to learning one new programming language a year. In the past, I’ve called this “the perennial Java problem”, referring to my search to find a language that “sucks less than Java”. This is a bit vague and perhaps unnecessarily offensive, so let me clarify it by saying I want to find a language that “can be used for actual programming and is less verbose than Java.” With that, I’ve been reading Dave Thomas’ Programming Elixir, an excellent read for programmers looking to learn the Elixir programming language. Since the idea is to use Elixir in a “real world app”, let’s go over what Elixir looks like for an app I wrote to help me get better at chess.
The Big Picture
While I learn a lot about a language from reading about it, I definitely learn a lot more by actually doing something with it. So while I was watching Daniel Rensch’s video on Full Board Awareness I saw an easy opportunity to write a program that does one of the exercises. The exercise is summarized as follows:
Have a partner pick a random square on a chess board and name it to you. You name if the square is white or black. Your partner informs you if this is correct and repeats this process (typically 20 to 25 times).
Of course, “a partner” will be “a program” for this exercise, but it seems like something simple enough to get my hands dirty in Elixir. Let’s see what it actually looks like!
So like other programming languages, we have a
main function that we can use as an entry point for our program. Let’s look at what ours is:
1 2 3 4 5 6 7 8 9
|> and operators are likely to be the biggest sources of confusion in this example, so let’s take a look at what they do. The
: denotes an atom, so if you’ve messed around with Ruby or Erlang, this won’t be new for you. Basically it’s a string constant, but the interesting thing about Elixir is that everything is a function, so
:random.seed is actually invoking a function named
seed in the
random module. Since Elixir runs on the Erlang VM, this is an easy way to invoke Erlang functions. With that in mind, it’s straightforward to see that the line
just seeds the runtime’s random number generator to the current time. The pipeline operator
|> is much more interesting to me though, so let’s take a look at that. The idea behind the pipeline operator is that it’s very common for a developer to write code like this:
Writing it like this is fine, but is difficult to understand when I come back to it at a later time. This is because the way I think of it is:
Elixir’s pipeline operator very nicely solves this problem. It means that instead of writing this:
I can simply write this:
1 2 3 4 5
Another cool and interesting thing about Elixir is that there’s no
for construct, which effectively forces recursion as the means by which looping is done. For example, here’s the main meat of my program:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
It gets invoked by
quiz_user, which simply starts the process and counts how many questions the user got correct (indicated by
true in the resulting list):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
The pattern matching in function definitions is what makes Elixir really cool as far as I’m concerned. We call
ask_question(n), and it will result in questions being asked until zero questions are left. For something like
ask_question(3), it would look like this (assuming the user guesses all questions correctly):
1 2 3 4 5
We also use recursion as the very last part of our function (as opposed to something like
[ask_question(n-1) | this_answer]) since Elixir has some neat tail call optimization tricks it does to free up stack space.
For the interested, all of the code in this program is open source and available on GitHub. I still need to add in better unit test coverage, and learn how to mock out things like I/O (so I can put in fake answers from the user in my unit tests). I’ve also been watching the original video I linked to above and thinking about how to (1) put a web interface on it instead of a command-line interface, and (2) adding in other exercises to keep my visualization skills sharp.
I’m also still reading the Elixir book, and am currently at the chapter about how Elixir does distributed computation. It’s actually really cool, so once I get through the remainder of the book I’ll see if there’s some useful way to shoehorn that stuff in. Regardless, I definitely recommend picking up Dave Thomas’ excellent Programming Elixir – it’s an intuitive introduction to the language that teaches you more than enough to get actual things done with Elixir, which is much more than I can say for other books and instantly justifies the purchase price. Happy coding!