Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problems understanding sequential Erlang

Tags:

erlang

I have been examining a code example and I cannot understand what is happening, I have tried to understand easier examples and get them but at this one I am getting stuck:

seq([X, X | Xs]) -> [X | seq(Xs)];
seq([X, Y | Xs]) -> [X, Y | seq(Xs)];
seq(_) -> [].

When I run it in the shell with [1,1,1,2,2,2,3] I get [1,1,2,2]. I have been trying to understand the steps by writing it on paper but I got stuck halfway trough.

I would appreciate all answers explaining me the steps happening here! :) /Eri.

like image 565
Eri. Avatar asked Dec 06 '22 03:12

Eri.


1 Answers

Ok, so we start with a list of [1,1,1,2,2,2,3].

On the first call to seq, erlang will match the first two elements 1 and 1 to the first "clause" of seq - seq([X, X | Xs]). This will initialize the list that will become the final return value, [1, seq(Xs)]. Now at this point Xs will be bound to the value [1,2,2,2,3]. If you're wondering why there aren't two 1's at the beginning of the Xs list it's because we matched/bound two of them on [X, X | Xs].

Return value = [1 | ?] (? is the remaining recursion to be evaluated)
Xs = [1,2,2,2,3]

On the second call to seq, erlang will match the first two elements of the input list 1 and 2 to the second clause seq([X, Y | Xs]). We then "return" the list [X, Y] or [1, 2] from this run, and call the next iteration with Xs = [2,2,3].

Return value = [1 | [1, 2 | ?]] <- See how recursion nests the lists?
Xs = [2,2,3]

On the third call, the first two elements are the same again, so erlang runs the first clause again. seq([X, X | Xs]) -> [X | seq(Xs)]. We return a single 2 value as part of the evaluation, and call seq([3]).

Return value = [1 | [1, 2 | [2 | ?]]]
Xs = [3]

At last, the final case. Our list of [3] doesn't match [X, X | Xs] nor [X, Y, Xs], so erlang will run our catch-all: seq(_) -> []. _ will match anything, and not bind the value to any local variables, so all we do here is return an empty list [].

Our final return value then is: [1 | [1, 2 | [2 | []]]]. If you evaluate this into your erl repl, you'll see it's the same as the list [1,1,2,2], the later is syntactic sugar for the former.

like image 136
Alex Moore Avatar answered Dec 18 '22 05:12

Alex Moore