Img_5845-srgb_small Jared Haworth 2 posts

Hi everyone,

So, I’ve finally found some time to get back into the Erlang book, and I was looking over some code as a bit of a refresher.

I’m kind of confused by the output of the mylists:map/2 function (and by extension, the output of the standard lists:map/2).


map(_, [])     -> [];
map(F, [H|T])  -> [F(H)|map(F, T)].

The output of the second clause builds a new list with H being the result of F(H) and the tail is a recursive call to map(F, T).

When I try to map this out on paper, using input such as L = [1, 2, 3, 4, 5], and fun(X) -> 2*X end as the fun being passed in as the first parameter, why isn’t the output [2, [4, [6, [8, [10]]]]] ?

Is it something particular to the internals of Erlang, or my own misunderstanding of recursive functions?

Thanks!

 
Generic-user-small Alain O'Dea 18 posts

The expression [Head|Tail] in Erlang takes head as an item and Tail as a list. For example [1|[2,3,4,5]] results in [1,2,3,4,5]. In the other direction, [Head|Tail]=[1,2,3,4,5] results in Head=1 and Tail=[2,3,4,5].

The following is my impression of how Erlang would execute your example:

First recursion:
map(F, [H=1|T=[2,3,4,5]]) -> [2*1|map(F, [2,3,4,5])
Second recursion:
map(F, [H=2|T=[3,4,5]]) -> [2*2|map(F, [3,4,5])
Third recursion:
map(F, [H=3|T=[4,5]]) -> [2*3|map(F, [4,5])
Fourth recursion:
map(F, [H=4|T=[5]]) -> [2*4|map(F, [5])
Fifth recursion:
map(F, [H=4|T=[]]) -> [2*5|map(F, [])
Sixth recursion:
map(_, []) -> []) -> []
Construct fifth:
[2*5|[]] -> [10]
Construct fourth:
[2*4|[10]] -> [8,10]
Construct third:
[2*3|[8,10]] -> [6,8,10]
Construct second:
[2*2|[6,8,10]] -> [4,6,8,10]
Construct result:
[2*1|[4,6,8,10]] -> [2,4,6,8,10]

 
Img_5845-srgb_small Jared Haworth 2 posts

I guess it’s a side effect of coming from Ruby, where I’m accustomed to having to flatten and compact my arrays all the time; putting [1|[2,3,4,5]] into the Eshell gave me back [1,2,3,4,5], in harmony with your examples above.

I think the fact that the functions above return all their output in a list is probably what threw me off track, it looked like the return would be coming back as a series of nested lists.

Thanks!

3 posts, 2 voices