Second day with Erlang, this time to cover basic controls, and more functional goodies such as anonymous and higher-order functions, list functions and list comprehensions.
Erlang’s support for list processing is quite extensive (as it should be for a language with limited mutable state). Using is properly requires the kind of mental twist that is needed for effective (set oriented) SQL usage. But once acquired, it is hard to get back to generic imperative programming.
This chapter introduces various functions from the
lists:foreach. I probably should not have used the former in yesterday’s “Counting to 10” exercise. The latter was more appropriate:
1 2 3 4 5 6 7 8 9 10 11 12
(also changed: I’m using the tilde format escape character, rather than backslash. Erlang is a child of Lisp, not C).
Just using pattern matching, the solution is very short an clean.
I named the module
dictionary as the name
dict was already used in the standard library. Erlang has a flat module naming system, so conflicts are bound to happen.
As it happens, Erlang
lists:keyfind already implements this feature, as shown in
1 2 3 4 5 6 7 8 9
Testing the code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
Once again, pattern matching makes it really easy to write such function. For extra credit (ok, no credit. Just for fun), I also wrote a function that depends on
It just shows how easy it is to process lists of things in Erlang or any other decent functional language (one with pattern matching and list comprehension, that is).
1 2 3 4 5 6
Testing both functions, they return the same answer (always a good thing for functions meant to have identical meaning):
1 2 3 4 5 6 7 8 9 10 11
I have to admit I cannot stand hard coding anything. Whenever I have a choice between hard coding and generating coding, I’ll pick the latter every single time.
So for the Tic-Tac-Toe exercise, I wrote code that computes the list of potential victory lines, even though the list for a board of 3 by 3 is much shorter. When Tic-Tac-Toe is finally played on 19 by 19 boards (as games for grown ups tend to be), my code will be ready…
I used a small utility module to transpose a matrix; the code is very similar, and indeed, lifted, from a previous Prolog exercise (the Sudoku one).
1 2 3 4 5 6 7 8 9 10 11 12
Once thing to note: as in the
export statement, a function name must include its arity when passed to higher order functions. See above for
fun head/1 for instance.
Once this is defined, the code for Tic-Tac-Toe is fairly simple:
- generate a list of lines on a board (
- for each of these lines, determine if it belongs to a single player (
tictactoe:check_align, called from
- if any player owns a line, declare her the winner (
- otherwise, depending on whether there is any non player own square, declare the game over or undecided (
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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
Testing is a bit tedious, because of the way the board is defined. First a winner on either diagonal is checked, then a draw, then an unfinished game:
1 2 3 4 5 6 7 8 9 10
Wrapping Up Day 2
Erlang functional features make it very concise (adding currying would be sweet, though); the resulting code is short, readable, and flexible.
Despite a non mainstream pedigree, clearly this is a language whose design has been guided by actual usage and experience.