Thursday, August 07, 2008

Erlang code snippet....

Code like that:

blah(X) ->
X1 = f(X),
X2 = g(X1),
X3 = h(X2),
i(X3).

is very error prone, and worse very hard to extend. Just adding another
function application between f(X) and g(X1) requires you to alter all lines
upto the end of the function:

blah(X) ->
X1 = f(X),
X2 = j(X1)
X3 = g(X2),
X4 = h(X3),
i(X4).

This causes 2*numberoflinestoendoffunction potential error sources;

And this is also not at all a very functional style.
Why not rewriting it like this:

blah(X) ->
(chain([
f,
g,
h,
i
]))(X).

where one chains together the functions. Adding a function invocation in between is as easy as pie.



chain(FunList) ->
lists:foldl(
fun combine/2,
fun id/1,
FunList).

id(X) -> X.

combine(F,G) ->
RF = to_local_function(F),
RG = to_local_function(G),
fun(X) ->
RF(RG(X))
end.

to_local_function(F) ->
case F of
{FM, FF} -> F;
_ when is_atom(F) -> {?MODULE, F}
end.

Another solution might be using the state monad, wich was
built for dealing with this kind of functional composition.

No comments: