Dabbling in Erlang, Part 2: A Minimal Introduction
agis.kontext.gr
agis.kontext.gr
> Note that the order of the definitions is important: had we moved our base case at the bottom, the recursion would never finish because map(F, [H|T]) would always match (remember? an empty list is also a list with a head and a tail).
Which confuses me a bit, since I am used to the empty list not having a head (I am thinking for example of Haskell). Is it true that in Erland the empty list has a head? And what would it be? Some generic null object?
map(F, [H]) -> [F(H)]; map(F, [H|T]) -> [F(H) | map(F, T)].
Order does matter
If you're looping over a million element list and your base case is first, it'll be checked a million times. If your base case is last, it'll only be checked once when your normal cases no longer match.
And to clear up your confusion, the writeup is wrong about empty lists matching on [H|T]:
Eshell V5.10.1 (abort with ^G)
1> [H|T] = [1, 2, 3, 4, 5].
[1,2,3,4,5]
2> [H2|T2] = [].
** exception error: no match of right hand side value []The VM will instead try to reorder the clauses up until the next guard clause, if possible.
You should mostly care about writing readable code and let the compiler and the VM do the rest.
> [H] = [].
** exception error: no match of right hand side value []
> [H|T] = [].
** exception error: no match of right hand side value []
But when it comes to pattern matching, order is important: > Test = fun(Value) -> Value ; (hello) -> world end.
> Test(hello).
hello
As opposed to: > Test2 = fun(hello) -> world ; (Value) -> Value end.
> Test2(hello).
world
---For the sake of completeness it's worth mentioning that a list with a single item has both a head and a tail:
> [H|T] = [1].
[1]
> H.
1
> T.
[]
(Which is why you need to have a function head that matches [], whether first or last in his example.)The empty list does not have a head, neither a tail, it's just an empty list.
I've replaced it with another example. Thanks for all the feedback by the way.
http://web.archive.org/web/20080708140354/http://www.stifflo...
I must shamelessly say it seems to have aged reasonably well, unlike some other things I wrote I actually read it now with interest, especially I haven't dabbled in Erlang since and forgot some details.
I recommend everyone who finds fun in programming to give Erlang a shot, I don't think it's great for all the use cases (what is?), but, for example, for writing servers of all kinds it's totally awesome, especially with OTP, which I didn't cover in my tutorial. It's also completely different from everything else, even if you know Prolog or Haskell/ML, which are related in some ways. One day I would really like to get myself together and write something like a game server for poker or bridge in it.
However, a factual error:: "(remember? an empty list is also a list with a head and a tail)."
An empty list is an empty list :) You could switch the order of those two function heads and 'map' would still behave properly.
[expression(element) || element <- list, conditions]
is the same as [expression(element) for element in list if condition]