Personalmente, prefiero la recursión en exceso en Erlang (a diferencia de otros idiomas, por ejemplo, Haskell). No veo el doblez más legible que la recursión. Por ejemplo:
fsum(L) -> lists:foldl(fun(X,S) -> S+X end, 0, L).
o
fsum(L) ->
F = fun(X,S) -> S+X end,
lists:foldl(F, 0, L).
vs
rsum(L) -> rsum(L, 0).
rsum([], S) -> S;
rsum([H|T], S) -> rsum(T, H+S).
parece más código, pero es bastante sencillo e idiomático Erlang. Usar fold requiere menos código pero la diferencia se vuelve más y más pequeña con más carga útil. Imagina que queremos un filtro y asignamos valores impares a su cuadrado.
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).
Aquí la lista de victorias de comprensión, pero es función recursiva en el segundo lugar y doblar versión es feo y menos legible.
Y, por último, no es cierto que el doblez sea más rápido que la versión recursiva, especialmente cuando se compila con código nativo (HiPE).
Editar: que añadir una versión pliegue con la diversión en la variable a lo solicitado:
ffoo2(L) ->
F = fun(X, A) when X band 1 =:= 1 -> [X|A];
(_, A) -> A
end,
lists:foldr(F, [], L).
no veo la forma en que es más fácil de leer que rfoo/1
y me encontré especialmente un acumulador de manipulación más complicada y menos obvio que la recursión directa. Es incluso un código más largo.
No olvide 'listas: zf/2'. Es un filtro de mapa, todo en uno. Con zf puede hacer 'listas: zf (diversión (X) cuando X banda 1 =: = 1 -> {verdadero, X * X}; (_) -> fin falso, L)'. Lamentablemente, zf no está documentado, por lo que no existe oficialmente ... –
¡Buena comparación de diferentes métodos! Creo que el doblez es más legible en su primer ejemplo, pero la diferencia es, por supuesto, bastante pequeña con una función tan simple. En su segundo ejemplo, en realidad encuentro fmfoo más legible que rfoo, pero por supuesto la comprensión de la lista gana mucho para ese problema. Todo esto muestra que realmente depende del desarrollador elegir la herramienta adecuada para el trabajo cada vez :-) –
Excelente respuesta por cierto +1. – Gilles