[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