I personally prefer recursion over the fold in Erlang (unlike other languages like Haskell). I do not see more understandable than recursion. For instance:
fsum(L) -> lists:foldl(fun(X,S) -> S+X end, 0, L).
or
fsum(L) -> F = fun(X,S) -> S+X end, lists:foldl(F, 0, L).
against
rsum(L) -> rsum(L, 0). rsum([], S) -> S; rsum([H|T], S) -> rsum(T, H+S).
There seems to be more code, but this is a fairly simple and idiomatic Erlang. Using fold requires less code, but the difference becomes smaller and smaller with a larger payload. Imagine that we want the filter to display odd values on their square.
lcfoo(L) -> [ X*X || X<-L, X band 1 =:= 1]. fmfoo(L) -> lists:map(fun(X) -> X*X end, lists:filter(fun(X) when X band 1 =:= 1 -> true; (_) -> false end, L)). ffoo(L) -> lists:foldr( fun(X, A) when X band 1 =:= 1 -> [X|A]; (_, A) -> A end, [], L). rfoo([]) -> []; rfoo([H|T]) when H band 1 =:= 1 -> [H*H | rfoo(T)]; rfoo([_|T]) -> rfoo(T).
Here the gain in the list looks, but the recursive function is in second place, and the reset version is ugly and less readable.
And finally, it is not true that fold is faster than the recursive version, especially when compiling into native (HiPE) code.
Edit : I add a resettable version with the loss of a variable as requested:
ffoo2(L) -> F = fun(X, A) when X band 1 =:= 1 -> [X|A]; (_, A) -> A end, lists:foldr(F, [], L).
I don't see how much more readable this is than rfoo/1
, and I found that manipulating the battery is more complicated and less obvious than direct recursion. This is an even longer code.