[erlang-questions] noob namespace question
Laszlo Lovei
lovei.laszlo@REDACTED
Sat Dec 15 15:54:55 CET 2012
On Wednesday, December 12, 2012 7:40:26 PM UTC+1, rusi wrote:
>
> On Thu, Dec 13, 2012 at 12:00 AM, Thomas Allen <tho...@REDACTED<javascript:>
> > wrote:
>
>> On Wed, Dec 12, 2012 at 11:44:43PM +0530, Rustom Mody wrote:
>> > I dont understand. Let me try and be more explicit about my concern.
>> >
>> > Let h be a higher-order function of one argument (h/1)
>> >
>> > Now in the call h(foo)
>> > How does Erlang know whether foo is a function or an atom?
>>
>> This is not valid, and you will get a "bad function" error if you try to
>> pass your function this way. You must create a "fun" like so:
>>
>> h(fun foo/0)
>>
>> Similarly, you could pass an anonymous fun (like fun(X) -> X end), or
>> a module-function combination (like fun lists:reverse/1).
>>
>>
> Thanks Thomas that answers succinctly.
>
That is a succinct but incorrect answer :) The call `h(foo)' is completely
valid, and might even refer to function `foo', although in a different way
than `h(fun foo/0)'.
I think the common source of misunderstanding here is that atoms are used
as both run time data and compile time identifiers. The expression `foo'
simply creates a data of type atom, without any additional meaning. This
data can be be used to identify something (a module, a function, a record,
a message - we don't know in advance) at run time. The expression `fun
foo/0' however creates a run time data of type function reference to
function foo, and the atom foo itself is only used to identify the function
at compile time. The same thing happens in expression `foo()', which is
compiled into a function call to function foo, without actually involving
the atom foo at run time.
The connection between the compile time identifiers of functions and run
time atom data is that exported functions are identified by atom data at
run time, instead of atom identifiers at compile time. So the expression
`m:foo()' means "look up a function with identifier foo in the export table
of module m, and call that function", where both atom m and atom foo are
run time data. You can even use arbitrary expressions to compute the module
or function name, so for example `h(F) -> m:F().' is valid code, and
calling `h(foo)' means the same as `m:foo()'. Note that you can't do this
with local functions: the code `h(F) -> F().' works only when F is a
function reference, so it must be called as `h(fun foo/0)'. This is what
Thomas meant.
In `h(foo)', we don't know whether the atom foo stands for a function or
something else - `h(M) -> M:bar().' is also valid code, and in this case
`h(foo)' means the same as `foo:bar()', so foo turns out to be a module
name. Or you can write `h(Tag) -> receive {Tag, Data} -> Data end.', in
this case `h(foo)' means "wait for a message tagged with foo". And you can
even choose between these meanings at run time.
L.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20121215/bfde04b1/attachment.htm>
More information about the erlang-questions
mailing list