[erlang-questions] Sending fun/1 over the network and apply/2 failure

Mikael Pettersson <>
Mon Jul 25 13:49:29 CEST 2016


Sid Muller writes:
 > Hi everyone,
 > 
 > I am having an issue that I don't really understand why it's happening.
 > 
 > In the shell I create a fun on one node:
 > Fa = fun(A)->A end.
 > #Fun<erl_eval.6.50752066>
 > 
 > Then call term_to_binary()
 > 
 > which gives me the following:
 > 
 > <<131,112,0,0,2,158,1,96,205,72,68,75,104,221,132,114,190,222,211,56,153,90,202,0,0,0,6,0,0,0,1,100,0,8,101,114,108,95,101,118,97,108,97,6,98,3,6,106,66,103,100,0,13,110,111,110,111,100,101,64,110,111,104,111,115,116,0,0,0,33,0,0,0,0,0,104,4,106,104,2,100,0,4,101,118,97,108,112,0,0,1,161,3,158,126,91,59,128,49,98,27,137,222,82,19,201,52,153,138,0,0,0,21,0,0,0,4,100,0,5,115,104,101,108,108,97,21,98,4,243,242,217,103,100,0,13,110,111,110,111,100,101,64,110,111,104,111,115,116,0,0,0,33,0,0,0,0,0,104,2,100,0,5,118,97,108,117,101,112,0,0,0,96,2,158,126,91,59,128,49,98,27,137,222,82,19,201,52,153,138,0,0,0,5,0,0,0,1,100,0,5,115,104,101,108,108,97,5,98,4,243,242,217,103,100,0,13,110,111,110,111,100,101,64,110,111,104,111,115,116,0,0,0,33,0,0,0,0,0,103,100,0,13,110,111,110,111,100,101,64,110,111,104,111,115,116,0,0,0,27,0,0,0,0,0,98,0,0,32,15,112,0,0,0,208,1,158,126,91,59,128,49,98,27,137,222,82,19,201,52,153,138,0,0,0,12,0,0,0,3,100,0,5,115,104,101,108,108,97,12,98,4,243,242,217,103
 >  ,100,0,13,110,111,110,111,100,101,64,110,111,104,111,115,116,0,0,0,33,0,0,0,0,0,104,2,100,0,5,118,97,108,117,101,112,0,0,0,96,2,158,126,91,59,128,49,98,27,137,222,82,19,201,52,153,138,0,0,0,5,0,0,0,1,100,0,5,115,104,101,108,108,97,5,98,4,243,242,217,103,100,0,13,110,111,110,111,100,101,64,110,111,104,111,115,116,0,0,0,33,0,0,0,0,0,103,100,0,13,110,111,110,111,100,101,64,110,111,104,111,115,116,0,0,0,27,0,0,0,0,0,98,0,0,32,15,103,100,0,13,110,111,110,111,100,101,64,110,111,104,111,115,116,0,0,0,27,0,0,0,0,0,103,100,0,13,110,111,110,111,100,101,64,110,111,104,111,115,116,0,0,0,27,0,0,0,0,0,104,2,100,0,5,118,97,108,117,101,112,0,0,0,96,2,158,126,91,59,128,49,98,27,137,222,82,19,201,52,153,138,0,0,0,5,0,0,0,1,100,0,5,115,104,101,108,108,97,5,98,4,243,242,217,103,100,0,13,110,111,110,111,100,101,64,110,111,104,111,115,116,0,0,0,33,0,0,0,0,0,103,100,0,13,110,111,110,111,100,101,64,110,111,104,111,115,116,0,0,0,27,0,0,0,0,0,108,0,0,0,1,104,5,100,0,6,99,108,97,117,115,101,97,1,108,0
 >  ,0,0,1,104,3,100,0,3,118,97,114,97,1,100,0,1,65,106,106,108,0,0,0,1,104,3,100,0,3,118,97,114,97,1,100,0,1,65,106,106>>
 > 
 > Now if I cut and paste this into another console like this:
 > 
 > Fa = binary_to_term(<<131,112,0,0,2,158,1,96,205,72,68,75,104,221,132,114,190,222,211,56,153,90,202,0,0,0,6,0,0,0,1,100,0,8,101,114,108,95,101,118,97,108,97,6,98,3,6,106,66,103,100,0,13,110,111,110,111,100,101,64,110,111,104,111,115,116,0,0,0,33,0,0,0,0,0,104,4,106,104,2,100,0,4,101,118,97,108,112,0,0,1,161,3,158,126,91,59,128,49,98,27,137,222,82,19,201,52,153,138,0,0,0,21,0,0,0,4,100,0,5,115,104,101,108,108,97,21,98,4,243,242,217,103,100,0,13,110,111,110,111,100,101,64,110,111,104,111,115,116,0,0,0,33,0,0,0,0,0,104,2,100,0,5,118,97,108,117,101,112,0,0,0,96,2,158,126,91,59,128,49,98,27,137,222,82,19,201,52,153,138,0,0,0,5,0,0,0,1,100,0,5,115,104,101,108,108,97,5,98,4,243,242,217,103,100,0,13,110,111,110,111,100,101,64,110,111,104,111,115,116,0,0,0,33,0,0,0,0,0,103,100,0,13,110,111,110,111,100,101,64,110,111,104,111,115,116,0,0,0,27,0,0,0,0,0,98,0,0,32,15,112,0,0,0,208,1,158,126,91,59,128,49,98,27,137,222,82,19,201,52,153,138,0,0,0,12,0,0,0,3,100,0,5,115,104,101,108,108,97,12,
 >  98,4,243,242,217,103,100,0,13,110,111,110,111,100,101,64,110,111,104,111,115,116,0,0,0,33,0,0,0,0,0,104,2,100,0,5,118,97,108,117,101,112,0,0,0,96,2,158,126,91,59,128,49,98,27,137,222,82,19,201,52,153,138,0,0,0,5,0,0,0,1,100,0,5,115,104,101,108,108,97,5,98,4,243,242,217,103,100,0,13,110,111,110,111,100,101,64,110,111,104,111,115,116,0,0,0,33,0,0,0,0,0,103,100,0,13,110,111,110,111,100,101,64,110,111,104,111,115,116,0,0,0,27,0,0,0,0,0,98,0,0,32,15,103,100,0,13,110,111,110,111,100,101,64,110,111,104,111,115,116,0,0,0,27,0,0,0,0,0,103,100,0,13,110,111,110,111,100,101,64,110,111,104,111,115,116,0,0,0,27,0,0,0,0,0,104,2,100,0,5,118,97,108,117,101,112,0,0,0,96,2,158,126,91,59,128,49,98,27,137,222,82,19,201,52,153,138,0,0,0,5,0,0,0,1,100,0,5,115,104,101,108,108,97,5,98,4,243,242,217,103,100,0,13,110,111,110,111,100,101,64,110,111,104,111,115,116,0,0,0,33,0,0,0,0,0,103,100,0,13,110,111,110,111,100,101,64,110,111,104,111,115,116,0,0,0,27,0,0,0,0,0,108,0,0,0,1,104,5,100,0,6,99,108,97,11
 >  7,115,101,97,1,108,0,0,0,1,104,3,100,0,3,118,97,114,97,1,100,0,1,65,106,106,108,0,0,0,1,104,3,100,0,3,118,97,114,97,1,100,0,1,65,106,106>>).
 > 
 > I get:
 > #Fun<erl_eval.6.50752066>
 > 
 > And then I call:
 > apply(Fa, ["Param"]).
 > 
 > And the code works fine, as long as I do that on the console.
 > 
 > But if I do that in erlang code and send the binary over the network, and I print it to make sure that it's the same as the binary above. Then when I call apply it fails. I get this:
 > 
 > Error in process <0.5040.1> with exit value:
 > {{badfun,#Fun<erl_eval.6.50752066>}, ....
 > 
 > 
 > I am completely lost why cut and paste works from the console but from erlang code it fails, even though everything is the same, both binary and the parameters I'm passing to apply/2.
 > 
 > What am I missing, does anyone have any pointers? I find it very strange...

A closure only contains a reference to its code, not a copy of the code
itself.  Taking a closure created in module M, passing it to another
Erlang node and applying it there, requires that the module M is present
there as well.  If it isn't, or if the modules differ too much, you get
a badfun exception.

The code part of a closure created in the shell refers to a module in
the Erlang interpreter (erl_eval or something like that) with the actual
expression being a plain term in the closed over free variables (which
the module can interpret).  That's why the shell's closures work in some
cases where closures from beam files don't.


More information about the erlang-questions mailing list