On Wednesday, December 12, 2012 7:40:26 PM UTC+1, rusi wrote:<blockquote class="gmail_quote" style="margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div class="gmail_quote">On Thu, Dec 13, 2012 at 12:00 AM, Thomas Allen <span dir="ltr"><<a href="javascript:" target="_blank" gdf-obfuscated-mailto="mIy169zlROoJ">tho...@oinksoft.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div>On Wed, Dec 12, 2012 at 11:44:43PM +0530, Rustom Mody wrote:<br>
> I dont understand. Let me try and be more explicit about my concern.<br>
><br>
> Let h be a higher-order function of one argument (h/1)<br>
><br>
> Now in the call h(foo)<br>
> How does Erlang know whether foo is a function or an atom?<br>
<br>
</div>This is not valid, and you will get a "bad function" error if you try to<br>
pass your function this way. You must create a "fun" like so:<br>
<br>
  h(fun foo/0)<br>
<br>
Similarly, you could pass an anonymous fun (like fun(X) -> X end), or<br>
a module-function combination (like fun lists:reverse/1).<br>
<span></span><br></blockquote></div><br>Thanks Thomas that answers succinctly.<br></blockquote><div><br>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)'.<br><br>
</div>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.<br><br>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.<br><br>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.<br><br><br>L.<br>