Fun syntax

Erik.Stenman <>
Tue Jul 30 11:20:53 CEST 2002


Vlad Dumitrescu wrote:

> Hi,
> 
> I am a little confused about the syntax for functional objects when the 
> referred function is remote. The way to define a fun is then
>     Fun = {lists, reverse}

No, it is not. Don't tell anyone that this works ;)
The way to do it is:
Fun = fun(L) -> lists:reverse(L) end.
 
> I find this a little inconsequent. Why not
>     Fun = fun lists:reverse/1 ?

I think the reason is that the entity lists:reverse/1 does not exist at compile time, the address of the function can only be found at load time or at the time of the call. If you create a fun like:
Fun = reverse/1, then Fun is just an alias for the local function reverse/1 which can be found during compilation.
One could argue that fun lists:reverse/1 could be syntactic sugar for  fun(L) -> lists:reverse(L) end, but this might lead one to belive that this fun only depend on the module lists but in fact it would also depend on the current module (there would be alocal fun calling lists:reverse/1).


> What I find even strange is that it works to write something like
>     {lists, reverse}([1,2,3]). 
> Wouldn't it be cleaner with an unified syntax for funs? The tuple notation 
> looks like remains from the old, while it working side by side with the 
> normal Module:Function notation feels almost like a bug... Is it?

Yes, this is terrible and ugly in so many ways... and it is going to go away.
The reason this still exists is because of the interaction with code updates.
In some generic servers you want to store dynamic callback functions. If you send a closure (fun) to these servers and then update the module that contained that closure the server will (probably) crash when trying to call the callback. But if you send it a tuple it will do a dynamic apply and the callback will work regardles of code updates (provided of course that the new module still implements the callback function in the same way.) 
e.g.
 s(MF) -> 
  receive 
   {call,Arg} -> MF(Arg), s(MF);
    _ -> s(MF)
end.
  
But this can be expressed just as well with apply:
s(MF={M,F}) -> 
  receive 
   {call,Arg} -> apply(M,F,[Arg]), s(MF);
    _ -> s(MF)
end.


/Erik
-------------------------------------- 
 Eric Conspiracy Secret Laboratories       
I'm Happi, you should be happy.
Praeterea censeo "0xCA" scribere Erlang posse.

 




More information about the erlang-questions mailing list