[erlang-questions] Question about higher order function

Kostis Sagonas kostis@REDACTED
Fri Nov 30 20:41:29 CET 2007


Burkhard Neppert wrote:
> Hello,
> 
> I try to use higher order functions but cannot pass  functions as  
> argument unless I wrap them in an anonymous function.
> Can someone tell me if I'm doing something wrong here or if Erlang is 
> really so akward and clumsy why it is this way?

Not knowing a language and trying to learn it is OK - it's a very good 
thing actually.

Not knowing a language and characterizing it with adjectives such as 
"awkward", "clumsy" and "terrible" is not particularly constructive
in my opinion.

> -module(HOF).
> -export([first/1]).
> fst({A,B}) -> A.
> % This does not compile
> % first(L) ->
> %    lists:map(fst, L).
> % but this does:
> first(L) ->
>     lists:map(fun (E) -> fst(E) end, L). % but this is terrible

First of all, please pay attention to details.  The above module does 
not compile in Erlang anyway: it has a variable (HOF) as its module name.

If you save this in a file hof.erl and rename the module to hof, as in 
the following:

-module(hof).
-export([first/1]).
fst({A,B}) -> A.
% This does not compile
first(L) ->
    lists:map(fst, L).

it will compile alright but it will give you some warnings:

./hof.erl:3: Warning: function fst/1 is unused
./hof.erl:3: Warning: variable 'B' is unused

The first warning says that the function fst/1 is unused.  Notice that 
functions do not just have a sequence of alphanumeric characters as 
their name but also an arity (i.e. the number of their arguments).  You 
can see already that something is going on here.  Indeed, in Erlang you 
can use the same 'character sequence' with different number of arguments 
and these are different functions.  This is something that you cannot do 
in languages such as C (because C also supports functions with variable 
number of arguments) or Haskell (because Haskell supports currying).
Whether this is something terrible or not is to a large extent a matter 
of personal taste.

Anyway, the point of the above is that to refer to functions in Erlang 
you really have to supply the number of their arguments.  This can be 
done in either of the following two ways:

   - explictly as in:

	lists:map(fun fst/1, L).

     (the keyword fun is needed here to distinguish this from division)

   - implictly with an anonymous function as in:

	lists:map(fun(E) -> fst(E) end, L).

If you do not write one of the above, but write lists:map(fst, L) 
instead as in your first attempt, Erlang simply trust that you really 
know what you are doing and want to use your own hacked up version of 
the 'lists' module (in Erlang you are actually allowed to override the 
default library  'lists' module -- why shouldn't you?) that defines a 
function map/2 which takes an atom in its first argument.

Hope this detailed explanation helps to introduce you a bit to the 
"philosophy" of Erlang.

Best,
Kostis



More information about the erlang-questions mailing list