Erlang/OTP Forums

Author Message

<  Erlang questions mailing list  ~  clarify: variable as function name

Guest
Posted: Mon Dec 10, 2007 10:27 am Reply with quote
Guest
Hi all!

A quote from the reference manual:
http://www.erlang.org/doc/reference_manual/expressions.html#6.6

6.6 Function Calls

ExprF(Expr1,...,ExprN)
ExprM:ExprF(Expr1,...,ExprN)

ExprM should evaluate to a module name and ExprF to a function name
or a fun.
[...]
The module name can be omitted, if ExprF evaluates to the name of a
local function, an imported function, or an auto-imported BIF.

This means that the following code is valid (F evaluates to a local
function name):

f() -> ok.
g() -> F=f, F().

In practice, this aborts with the reason badfun. The question is, which
one is considered good: the manual, or the implementation?


Thanks!
Laszlo
_______________________________________________
erlang-questions mailing list
erlang-questions@erlang.org
http://www.erlang.org/mailman/listinfo/erlang-questions
Post recived from mailinglist
Guest
Posted: Mon Dec 10, 2007 11:24 am Reply with quote
Guest
The proper syntax should be:

noss
Posted: Mon Dec 10, 2007 11:39 am Reply with quote
User Joined: 09 Oct 2005 Posts: 290
On Dec 10, 2007 12:21 PM, Anthony Kong <anthony.hw.kong@gmail.com> wrote:
> It is because if you simply put 'f' there, it is considered an atom, not a
> function. Hence the 'badfun'.

Thus, it seems like Lovei has found an inconsistency with
documentation/implementation. I believe we want to move away from
the implicit assumption that an atom is the name of a function.
Similarity with the old Call = {M, F}, Call(Args...) which is to be
superseeded
by Call = fun M:F/Arity, Call(Args...) in all new code (and old code
too, if you have time Smile.
_______________________________________________
erlang-questions mailing list
erlang-questions@erlang.org
http://www.erlang.org/mailman/listinfo/erlang-questions
Post recived from mailinglist
View user's profile Send private message
Guest
Posted: Mon Dec 10, 2007 11:42 am Reply with quote
Guest
Lovei Laszlo wrote:
> 6.6 Function Calls
>
> ExprF(Expr1,...,ExprN)
> ExprM:ExprF(Expr1,...,ExprN)
>
> ExprM should evaluate to a module name and ExprF to a function name
> or a fun.
> [...]
> The module name can be omitted, if ExprF evaluates to the name of a
> local function, an imported function, or an auto-imported BIF.
>
> This means that the following code is valid (F evaluates to a local
> function name):
>
> f() -> ok.
> g() -> F=f, F().
>
> In practice, this aborts with the reason badfun. The question is, which
> one is considered good: the manual, or the implementation?

The implementation, most definitely. The reference manual apparently
tries to give a very condensed description of function calls, and fails
miserably.

- The two forms ExprF(Expr1,...,ExprN) and ExprM:ExprF(Expr1,...,ExprN)
need to be explained separately; they are too different.

- In the case of a call ExprF(Expr1,...,ExprN):

* ExprF can be a constant atom (lexically), or otherwise it must
be an expression which evaluates to a fun. Nothing else is
possible. (In particular, no dynamically computed atoms.)
ExprF usually needs parentheses around it if it is not an
atom or a variable.

* The handling of the constant atom thing is as follows: If the
code contains <atom>(a1,...,aN), and <atom>/N is the name of a
function imported (explicitly or automatically) from module M,
then the call is rewritten as M:<atom>(a1,...,aN). Otherwise,
the function <atom>/N must be a locally defined function, and
the call is equivalent to (fun <atom>/N)(a1,...,aN).

* This slight syntactic weirdness is due to the fact that lexically,
Erlang uses atoms, not variables, to name functions. It's a
remnant from Erlang's roots in Prolog. It gets strange sometimes
but we can live with it.

- In the case of a remote call ExprM:ExprF(Expr1,...,ExprN):

* ExprF must evaluate to an atom; it cannot be a fun.

* ExprM must evaluate to an atom (or, inofficially, to a value that
represents an instance of an abstract module).

* It does not matter if ExprM and ExprF are lexically atoms or not.
However, the compiler can generate a bit more efficient code
if both ExprM and ExprF are known at compile time.

/Richard
_______________________________________________
erlang-questions mailing list
erlang-questions@erlang.org
http://www.erlang.org/mailman/listinfo/erlang-questions
Post recived from mailinglist
Guest
Posted: Mon Dec 10, 2007 12:03 pm Reply with quote
Guest
Lovei Laszlo wrote:

> f() -> ok.
> g() -> F=f, F().
>
> In practice, this aborts with the reason badfun. The question is, which
> one is considered good: the manual, or the implementation?

Try

g() -> F=fun f/0, F().

The F=f just assigns the atom 'f' to F, and that's not a function.

Robby

_______________________________________________
erlang-questions mailing list
erlang-questions@erlang.org
http://www.erlang.org/mailman/listinfo/erlang-questions
Post recived from mailinglist
Guest
Posted: Mon Dec 10, 2007 12:57 pm Reply with quote
Guest
I am missing the ability to send Variables to "fun [xxx:]yyy/z".

Something like:
F = fun ExprF/0.

And:
F = fun ExprM:ExprF/0.

Where the look up to a function is performed only once when the fun
operation is executed. And where calls to F() should be as fast/slow
as the:
F = fun yyy/0.
Or:
F = fun xxx:yyy/0.


Another question: Should it be possible to bind BIF's to fun's not
specifying module?
F = fun time/0.
Instead of:
F = fun erlang:time/0.
I think it is OK like it is. But I take it up for discussion.


Kind regards,
Andreas Hillqvist

2007/12/10, Richard Carlsson <richardc@it.uu.se>:
> Lovei Laszlo wrote:
> > 6.6 Function Calls
> >
> > ExprF(Expr1,...,ExprN)
> > ExprM:ExprF(Expr1,...,ExprN)
> >
> > ExprM should evaluate to a module name and ExprF to a function name
> > or a fun.
> > [...]
> > The module name can be omitted, if ExprF evaluates to the name of a
> > local function, an imported function, or an auto-imported BIF.
> >
> > This means that the following code is valid (F evaluates to a local
> > function name):
> >
> > f() -> ok.
> > g() -> F=f, F().
> >
> > In practice, this aborts with the reason badfun. The question is, which
> > one is considered good: the manual, or the implementation?
>
> The implementation, most definitely. The reference manual apparently
> tries to give a very condensed description of function calls, and fails
> miserably.
>
> - The two forms ExprF(Expr1,...,ExprN) and ExprM:ExprF(Expr1,...,ExprN)
> need to be explained separately; they are too different.
>
> - In the case of a call ExprF(Expr1,...,ExprN):
>
> * ExprF can be a constant atom (lexically), or otherwise it must
> be an expression which evaluates to a fun. Nothing else is
> possible. (In particular, no dynamically computed atoms.)
> ExprF usually needs parentheses around it if it is not an
> atom or a variable.
>
> * The handling of the constant atom thing is as follows: If the
> code contains <atom>(a1,...,aN), and <atom>/N is the name of a
> function imported (explicitly or automatically) from module M,
> then the call is rewritten as M:<atom>(a1,...,aN). Otherwise,
> the function <atom>/N must be a locally defined function, and
> the call is equivalent to (fun <atom>/N)(a1,...,aN).
>
> * This slight syntactic weirdness is due to the fact that lexically,
> Erlang uses atoms, not variables, to name functions. It's a
> remnant from Erlang's roots in Prolog. It gets strange sometimes
> but we can live with it.
>
> - In the case of a remote call ExprM:ExprF(Expr1,...,ExprN):
>
> * ExprF must evaluate to an atom; it cannot be a fun.
>
> * ExprM must evaluate to an atom (or, inofficially, to a value that
> represents an instance of an abstract module).
>
> * It does not matter if ExprM and ExprF are lexically atoms or not.
> However, the compiler can generate a bit more efficient code
> if both ExprM and ExprF are known at compile time.
>
> /Richard
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@erlang.org
> http://www.erlang.org/mailman/listinfo/erlang-questions
>
_______________________________________________
erlang-questions mailing list
erlang-questions@erlang.org
http://www.erlang.org/mailman/listinfo/erlang-questions
Post recived from mailinglist
noss
Posted: Mon Dec 10, 2007 1:28 pm Reply with quote
User Joined: 09 Oct 2005 Posts: 290
On Dec 10, 2007 1:47 PM, Andreas Hillqvist <andreas.hillqvist@gmail.com> wrote:
> I am missing the ability to send Variables to "fun [xxx:]yyy/z".
>
> Something like:
> F = fun ExprF/0.
>
> And:
> F = fun ExprM:ExprF/0.
>

If you look at the document in the source that describes the external
format you will see that this kind of fun (that just reference the fun to
call by its name) already exist.

If funs are bound to the offset and checksum into a module or if it is
just referencing
the names exposed by the external api has huge impact for code-switching.
It feels like this is the area where you just have to be very
experienced to know
how and when to use funs without painting youself into a corner about
how troublesome
code switching will be.
_______________________________________________
erlang-questions mailing list
erlang-questions@erlang.org
http://www.erlang.org/mailman/listinfo/erlang-questions
Post recived from mailinglist
View user's profile Send private message
Guest
Posted: Mon Dec 10, 2007 3:21 pm Reply with quote
Guest
I have read the documentation:
The following fun expressions are also allowed:
fun Name/Arity
fun Module:Name/Arity

In Name/Arity, Name is an atom and Arity is an integer.
Name/Arity must specify an existing local function.
The expression is syntactic sugar for:
fun (Arg1,...,ArgN) -> Name(Arg1,...,ArgN) end

Which dose not state that Module and/or Name could be variables containing atom.
So I guess I am proposing an addition to Erlang and should probably
write an EEP.
But lets first discuss the topic here.

If I write the following module:
-module(fun_test1).

-export([start/0]).
-export([hello/1]).

start() ->
F = make_fun(?MODULE, hello, 1),
F("Andreas").

hello(Name) ->
io:format("Hello ~p\n", [Name]).

make_fun(Module, Function, Arity) ->
fun Module:Function/Arity.

I receive the following error message using R12-0:
./fun_test1.erl:14: syntax error before: Module
./fun_test1.erl:7: function make_fun/3 undefined
error

I have now looked in to "Erlangs External Format and distribution protocol"
I think it would be plausible to transform:
fun Module:Function/Arity.
To a value of tag 113.

It is doable with something like:
make_fun(Module, Function, Arity)
when
is_atom(Module),
is_atom(Function),
Arity >= 0,
Arity < 255 ->

<<131, BinModule/binary>> = term_to_binary(Module),
<<131, BinFunction/binary>> = term_to_binary(Function),
<<131, BinArity/binary>> = term_to_binary(Arity),
Bin = <<131, 113, BinModule/binary, BinFunction/binary,
BinArity/binary>>,
binary_to_term(Bin).

I guess it is not possible to write a parse-transformer due to the
parser error.

The same problem applies to internal functions:
-module(fun_test4).

-export([start/0]).

start() ->
F = make_fun(hello, 1),
F("Andreas").

hello(Name) ->
io:format("Hello ~p\n", [Name]).

make_fun(Function, Arity) ->
fun Function/Arity.

Where I receive the following error message using R12-0:
./fun_test4.erl:13: syntax error before: Function
./fun_test4.erl:6: function make_fun/2 undefined
./fun_test4.erl:9: Warning: function hello/1 is unused

But i leave to list decide if this also should apply to internal
functions exported as funs?


Kind regards
Andreas Hillqvist

2007/12/10, Christian S <chsu79@gmail.com>:
> On Dec 10, 2007 1:47 PM, Andreas Hillqvist <andreas.hillqvist@gmail.com> wrote:
> > I am missing the ability to send Variables to "fun [xxx:]yyy/z".
> >
> > Something like:
> > F = fun ExprF/0.
> >
> > And:
> > F = fun ExprM:ExprF/0.
> >
>
> If you look at the document in the source that describes the external
> format you will see that this kind of fun (that just reference the fun to
> call by its name) already exist.
>
> If funs are bound to the offset and checksum into a module or if it is
> just referencing
> the names exposed by the external api has huge impact for code-switching.
> It feels like this is the area where you just have to be very
> experienced to know
> how and when to use funs without painting youself into a corner about
> how troublesome
> code switching will be.
>
_______________________________________________
erlang-questions mailing list
erlang-questions@erlang.org
http://www.erlang.org/mailman/listinfo/erlang-questions
Post recived from mailinglist
Guest
Posted: Mon Dec 10, 2007 6:49 pm Reply with quote
Guest
you need to specify the module:


f() -> ok.
g() -> F=f, ?MODULE:F().

h(X) -> M=erlang, F=is_integer, M:F(X).

the function h/1 works just fine since the module is specified,
the function g/0 works when a module is specified

On Dec 10, 2007 2:24 AM, Lovei Laszlo <lovei@elte.hu> wrote:
> Hi all!
>
> A quote from the reference manual:
> http://www.erlang.org/doc/reference_manual/expressions.html#6.6
>
> 6.6 Function Calls
>
> ExprF(Expr1,...,ExprN)
> ExprM:ExprF(Expr1,...,ExprN)
>
> ExprM should evaluate to a module name and ExprF to a function name
> or a fun.
> [...]
> The module name can be omitted, if ExprF evaluates to the name of a
> local function, an imported function, or an auto-imported BIF.
>
> This means that the following code is valid (F evaluates to a local
> function name):
>
> f() -> ok.
> g() -> F=f, F().
>
> In practice, this aborts with the reason badfun. The question is, which
> one is considered good: the manual, or the implementation?
>
>
> Thanks!
> Laszlo
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@erlang.org
> http://www.erlang.org/mailman/listinfo/erlang-questions
>
_______________________________________________
erlang-questions mailing list
erlang-questions@erlang.org
http://www.erlang.org/mailman/listinfo/erlang-questions
Post recived from mailinglist
rvirding
Posted: Mon Dec 10, 2007 10:06 pm Reply with quote
User Joined: 30 Aug 2006 Posts: 452 Location: Stockholm, Sweden
I think the main problem is that the documentation is a little unclear as to what should syntactically be an atom, or if not an atom what it can/should evaluate to. Unfortunately it is not consistent.

So with

View user's profile Send private message Visit poster's website MSN Messenger
rvirding
Posted: Mon Dec 10, 2007 10:54 pm Reply with quote
User Joined: 30 Aug 2006 Posts: 452 Location: Stockholm, Sweden
On 10/12/2007, Andreas Hillqvist <andreas.hillqvist@gmail.com (andreas.hillqvist@gmail.com)> wrote:
Quote:

View user's profile Send private message Visit poster's website MSN Messenger
Guest
Posted: Tue Dec 11, 2007 10:37 am Reply with quote
Guest
Would it be useful to be able to be able to explicitly create a fun of
an exported function, EXPORT_EXT (113) . It is an clean way of sending
a reference to a exported function.

I do not know ho efficent it is to call compared with an:
apply(Module, Function, [Args1, ... ArgsN]).
or a:
Module:Function(Args1, ... ArgsN).

I guess that my previous hack is a no, no.

But I guess it would be simple for the OTP team to add a "real"
make_fun(Module, Function, Arity) function that creates an EXPORT_EXT
(113) to a module i.e. the erlang module.
Then there is no syntax change as it would be for:
F = fun Module:Function/Arity.


Regards
Andreas Hillqvist

2007/12/10, Robert Virding <rvirding@gmail.com>:
> On 10/12/2007, Andreas Hillqvist <andreas.hillqvist@gmail.com> wrote:
> >
> > make_fun(Module, Function, Arity) ->
> > fun Module:Function/Arity.
>
> You can actually do it today:
>
> make_fun(M, F, 0) -> fun () -> M:F() end;
> make_fun(M, F, 1) -> fun (A1) -> M:F(A1) end;
> make_fun(M, F, 2) -> fun (A1, A2) -> M:F(A1, A2) end;
> ...
>
> Not beautiful but it works. The only limitation is that you can only reach
> exported functions. Which is as it should be.
>
> Robert
>
>
>
_______________________________________________
erlang-questions mailing list
erlang-questions@erlang.org
http://www.erlang.org/mailman/listinfo/erlang-questions
Post recived from mailinglist
Guest
Posted: Tue Dec 11, 2007 11:26 am Reply with quote
Guest
"Andreas Hillqvist" <andreas.hillqvist@gmail.com> writes:

> But I guess it would be simple for the OTP team to add a "real"
> make_fun(Module, Function, Arity) function that creates an EXPORT_EXT
> (113) to a module i.e. the erlang module.

There already is an erlang:make_fun/3 BIF. Not documented, though.

1> erlang:make_fun(c, i, 0).
#Fun<c.i.0>
2>

/Bjorn
--
Bj
Guest
Posted: Tue Dec 11, 2007 12:50 pm Reply with quote
Guest
Thank you for the information.

I feelt like there should be some sort of function for that. Wink

Is it OK to use it, will it made public/documented part of OTP?
Maybe in R12-1? Wink


Kind regards
Andreas Hillqvist

11 Dec 2007 12:11:35 +0100, Bjorn Gustavsson <bjorn@erix.ericsson.se>:
> "Andreas Hillqvist" <andreas.hillqvist@gmail.com> writes:
>
> > But I guess it would be simple for the OTP team to add a "real"
> > make_fun(Module, Function, Arity) function that creates an EXPORT_EXT
> > (113) to a module i.e. the erlang module.
>
> There already is an erlang:make_fun/3 BIF. Not documented, though.
>
> 1> erlang:make_fun(c, i, 0).
> #Fun<c.i.0>
> 2>
>
> /Bjorn
> --
> Bj
wuji
Posted: Wed Aug 15, 2012 6:46 am Reply with quote
User Joined: 10 Aug 2012 Posts: 654
nurse, started taking Adderall after reading a book that told told cheap Ralph Lauren Polo told her how to lie to her doctor to get
drug."Your life becomes a squirrel, just looking for that nut, nut, [h4]Cheap Ralph Lauren Shirts[/h4] nut, looking for that Adderall," she said.Some women start on
to keep up with the demands of career and home, home, [h3]Cheap Ralph Lauren Shirts[/h3] home, while others start looking for a quick weight loss
doctors say the situation is getting out of control."This is is replica designer bags for sale is a significant problem," said Dr. Marvin Seppala, chief medical
at Hazelden, an addiction treatment facility. "We've got an increase increase [h2]replica designer bags for sale[/h2] increase in women using drugs like Adderall ending up in
View user's profile Send private message

Display posts from previous:  

All times are GMT
Page 1 of 1
This forum is locked: you cannot post, reply to, or edit topics.

Jump to:  

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum