Higher Order Function Question

Alex Peake apeake@REDACTED
Sat May 25 18:08:15 CEST 2002

```Perhaps I could go back a step, to my orginal problem -- obviously not
stated clearly:

I was struggling to use "filter" with the "complement of" a predicate (in my
case not attr:isPk).

In explaining the problem, it came out that in my code I wrote things like:

lists:map({attr,varName}, rel:attrList(rel:findNamed(ng,"Member"))).

I was informed that this is "not elegant" and "inefficient" because it "is
the old classic version of how to call a fun".

So I asked for how to do this the "modern Erlang" way. I pointed out that:

lists:map(fun(Arg) -> attr:varName(Arg) end,
rel:attrList(rel:findNamed(ng,"Member"))).

is more efficient, but as programmer reading this, I find the fun...end part
makes the intent less clear.

Similarly:

Fn = fun attr:varName/1,
lists:map(Fn, rel:attrList(rel:findNamed(ng,"Member"))).

I also find cluttered.

Richard Carlsson suggested the very elegant approach using list
comprehensions:

[attr:varName(Attr) || Attr <- rel:findNamed(ng,"Member")]

This is what I am using.

None-the-less, I am learning Erlang and am interested in the "moderen
Erlang" way to use map, filter. Perhaps the answer is list comprehensions?

Alex

BTW, my solution to the filter with complement of a predicate, thanks to
Richard, is:

[attr:varName(Attr) || Attr <- rel:findNamed(ng,"Member"), not
attr:isPk(Attr)]

-----Original Message-----
From: Hakan Stenholm [mailto:hakan.stenholm@REDACTED]
Sent: Saturday, May 25, 2002 6:18 AM
To: erlang-questions@REDACTED
Cc: apeake@REDACTED
Subject: RE: Higher Order Function Question

>Thank you Haken,
>
>but the issue is not "apply" - I was only using that to experiment
>-- the issue is "map" or "filter" which, apparently, will only
>accept {attr, isPk} and not attr:isPk (which I am told is "more
>elegant" and certainly more efficient).
>
I think there has been slight missunderstanding here, apply(M,F,A) is the
old classic version of how to call a fun, modern erlang supports funs to be
called as F1(A) or M:F2(A) where F1 is a fun as defined previously:
> Fun = fun(Arg1, Arg2 ....) -> ... end % anynomouse fun
> Fun = fun FunctionName/Arity % local fun in current file
> Fun = {Module, FunctionName} % any exported function can be used
>
but it is also possible for M and F2 to be arbitrary atoms i.e. this can
also be done:

% define this function
my_apply(M,F2,A) -> M:F2(A).
% this can be called as
my_apply(lists,append,[[1,2],[3,4]])
% and result in [1,2,3,4]

But "Fun = lists:append," (or similar construct) is not a legal way to
define a fun. The F1(A) and M:F2(A) syntax is prefered to the apply(M,F,A)
syntax because it's more efficent in most cases (see the "performance hints"
link on the R8B documentation index.html page).

>map and filter will accept:
>
>lists:map(fun(Arg) -> attr:varName(Arg) end,
>rel:attrList(rel:findNamed(ng,"Member"))).
>
>but this is quite ugly looking code (albeit probably more efficient >than
{attr, isPk}...
>
>>Alex

```