<div dir="ltr"><div class="im" style="font-family:arial,sans-serif;font-size:13px"><span style="color:rgb(34,34,34)">>>The problem is that funs don't normally _have_ code available</span><br></div><span style="font-family:arial,sans-serif;font-size:13px">>>unless you compile the containing module with a special option.</span><br style="font-family:arial,sans-serif;font-size:13px">
<br style="font-family:arial,sans-serif;font-size:13px"><span style="font-family:arial,sans-serif;font-size:13px">>>Have you considered the alternative of accepting the *source code*</span><br style="font-family:arial,sans-serif;font-size:13px">
<span style="font-family:arial,sans-serif;font-size:13px">>>of a fun and parsing that?</span><br><div><span style="font-family:arial,sans-serif;font-size:13px"><br></span></div><div style><span style="font-family:arial,sans-serif;font-size:13px">I have considered this option but as far as possible we do not want to change any syntax. The final objective is to have the same spawn(N,F) syntax but which is capable of accepting and executing F on the remote node irrelevant of whether the code is there or not.</span></div>
<div style><span style="font-family:arial,sans-serif;font-size:13px"><br></span></div><div style><span style="font-family:arial,sans-serif;font-size:13px">>>Er, the free variables of a fun are _not_ the variables that are</span><br style="font-family:arial,sans-serif;font-size:13px">
<span style="font-family:arial,sans-serif;font-size:13px">>>in scope at its point of creation, they are that subset of those</span><br style="font-family:arial,sans-serif;font-size:13px"><span style="font-family:arial,sans-serif;font-size:13px">>>variables that are *used* inside the fun.</span><br style="font-family:arial,sans-serif;font-size:13px">
<br style="font-family:arial,sans-serif;font-size:13px"><span style="font-family:arial,sans-serif;font-size:13px">>>What a fun _is_, conceptually, is a tuple containing a code reference</span><br style="font-family:arial,sans-serif;font-size:13px">
<span style="font-family:arial,sans-serif;font-size:13px">>>and a set of variable bindings.  If someone gives you a fun, you know</span><br style="font-family:arial,sans-serif;font-size:13px"><span style="font-family:arial,sans-serif;font-size:13px">>>exactly what the values for those variables are because they are right</span><br style="font-family:arial,sans-serif;font-size:13px">
<span style="font-family:arial,sans-serif;font-size:13px">>>there.  A fun does not point back to the stack frame of its creator.</span><span style="font-family:arial,sans-serif;font-size:13px"><br></span></div><div style>
<font face="arial, sans-serif"><br></font></div><div style><font face="arial, sans-serif">Our intention is to change exactly this; i.e. what fun actually _is_. We are trying to change from the current ETF for fun to one containing also the function's code tree or some other presentation. Since fun does not point back to the stack frame, our current implementation is passing the required environment variables as part of the fun's parameter list, thus shadowing the original one. In practice</font></div>
<div style><font face="arial, sans-serif"><br></font></div><div style><b style="font-size:13px;color:rgb(0,0,0);font-family:sans-serif;line-height:19.1875px">ëx:x+y </b></div><div style><b style="font-size:13px;color:rgb(0,0,0);font-family:sans-serif;line-height:19.1875px"><br>
</b></div><div style><span style="font-size:13px;color:rgb(0,0,0);line-height:19.1875px"><font face="arial, sans-serif">becomes</font></span></div><div style><b style="font-size:13px;color:rgb(0,0,0);line-height:19.1875px"><font face="arial, sans-serif"><br>
</font></b></div><div style><b style="font-size:13px;color:rgb(0,0,0);font-family:sans-serif;line-height:19.1875px">ëx,y:x+y </b><span style="font-size:13px;color:rgb(0,0,0);font-family:sans-serif;line-height:19.1875px"><</span><span style="font-size:13px;color:rgb(0,0,0);font-family:sans-serif;line-height:19.1875px">- this gets serialized and transferred. </span><b style="font-size:13px;color:rgb(0,0,0);line-height:19.1875px"><font face="arial, sans-serif"><br>
</font></b></div><div style><span style="font-size:13px;color:rgb(0,0,0);font-family:sans-serif;line-height:19.1875px"><br></span></div><div style><span style="color:rgb(0,0,0);font-family:sans-serif;font-size:13px;line-height:19.1875px">In regards to version consistency, we are not using the original module name, but renaming to module@NodeName. This would not break anything on the remote node. It goes without saying that any code transferred to the remote node reflects this change in mod name.</span><br>
</div><div style><span style="font-size:13px;color:rgb(0,0,0);font-family:sans-serif;line-height:19.1875px"><br></span></div><div style><span style="font-size:13px;color:rgb(0,0,0);font-family:sans-serif;line-height:19.1875px">Thanks for your insight :)</span></div>
<div style><span style="font-family:arial,sans-serif;font-size:13px"><br></span></div><div style><span style="font-family:arial,sans-serif;font-size:13px"><br></span></div><div style><span style="font-family:arial,sans-serif;font-size:13px"> </span></div>
<div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Jan 28, 2013 at 12:40 AM, Richard O'Keefe <span dir="ltr"><<a href="mailto:ok@cs.otago.ac.nz" target="_blank">ok@cs.otago.ac.nz</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im"><br>
On 28/01/2013, at 12:11 AM, Tyron Zerafa wrote:<br>
<br>
> I want to build a call which accepts a fun, extracts all of its code and dependencies, pass everything over to a remote node and execute it there.<br>
<br>
</div>The problem is that funs don't normally _have_ code available<br>
unless you compile the containing module with a special option.<br>
<br>
Have you considered the alternative of accepting the *source code*<br>
of a fun and parsing that?<br>
<div class="im"><br>
> The only problem I am having is extracting the value of the free vars of such fun.<br>
<br>
</div>Er, the free variables of a fun are _not_ the variables that are<br>
in scope at its point of creation, they are that subset of those<br>
variables that are *used* inside the fun.<br>
<br>
What a fun _is_, conceptually, is a tuple containing a code reference<br>
and a set of variable bindings.  If someone gives you a fun, you know<br>
exactly what the values for those variables are because they are right<br>
there.  A fun does not point back to the stack frame of its creator.<br>
<br>
Let's take a look at a tiny example.<br>
<br>
foo(X, Y) -><br>
    M = (X+Y)/2,<br>
    fun (Z) -> {Z,M} end.<br>
<br>
Now let's look at the BEAM code.<br>
<br>
{function, foo, 2, 2}.<br>
  {label,1}.<br>
    {func_info,{atom,foo},{atom,foo},2}.<br>
  {label,2}.<br>
    % add Y to X; put the result back in X<br>
    {gc_bif,'+',{f,0},2,[{x,0},{x,1}],{x,0}}.<br>
    % check that there is room for two floats<br>
    {test_heap,{alloc,[{words,0},{floats,1}]},2}.<br>
    % convert X to floating point (in FR 0)<br>
    {fconv,{x,0},{fr,0}}.<br>
    % convert 2 to floating point (in FR 1)<br>
    %?? Why is this not done at compile time?<br>
    {fconv,{integer,2},{fr,1}}.<br>
    fclearerror.<br>
    % Divide FR 0 by FR 1 and put the result in FR 0.<br>
    {bif,fdiv,{f,0},[{fr,0},{fr,1}],{fr,0}}.<br>
    {fcheckerror,{f,0}}.<br>
    % Now that we know all went well, box the result<br>
    % and put it back in X.<br>
    {fmove,{fr,0},{x,0}}.<br>
    {'%live',1}.<br>
    % Create a fun, copying X (but not what X points to)<br>
    % into it.<br>
    {make_fun2,{f,8},0,98308069,1}.<br>
    return.<br>
<br>
{function, '-foo/2-fun-0-', 2, 8}.<br>
  {label,7}.<br>
    {func_info,{atom,foo},{atom,'-foo/2-fun-0-'},2}.<br>
    % {f,8} in the make_fun2 instruction points here.<br>
  {label,8}.<br>
    % Check that there is room for a 2-tuple<br>
    {test_heap,3,2}.<br>
    % start to create it, and let X2 point to it.<br>
    {put_tuple,2,{x,2}}.<br>
    % put in Z<br>
    {put,{x,0}}.<br>
    % put in M<br>
    {put,{x,1}}.<br>
    % move X2 down to X0<br>
    {move,{x,2},{x,0}}.<br>
    % return X0<br>
    return.<br>
<div class="im"><br>
> I was thinking about adding these to the parameter list of the fun,<br>
<br>
</div>As the code shows, the (selected) free variables _are_ hidden<br>
parameters of the fun.<br>
<div class="im"><br>
> i.e shadowing the respective vars.<br>
<br>
</div>?<br>
<br>
Finding the dependencies of a fun, at least those not already<br>
compiled inline, can be done from its BEAM code.  You do not<br>
need the source code.  What you cannot get, either way, is<br>
which _versions_ of the modules used the code depends on.<br>
<br>
And that creates a big problem.<br>
<br>
On local node L, send F1 to remote node R.<br>
F1 needs module M.<br>
Ensure that R has M loaded.<br>
But M on R is a completely different module from M on L.<br>
So send L to R as well and have it install that.<br>
Congratulations, you just broke everything else on R<br>
that used M.<br>
<br>
If you can manage version consistency to the point at<br>
which every node you try to send stuff to has the same<br>
versions of all the relevant modules you need, then you<br>
don't need to extract dependencies at run time.<br>
If you can't do that, it's not going to work anyway.<br>
<br>
This whole sending-code-to-a-remote-node business is to be done<br>
with *extreme* vigilant trepidation, if at all.<br>
<br>
Do you *really* want me to be able to call<br>
   your_module:your_handy_function(fun () -> halt() end)<br>
<br>
Consider whether it is possible to devise a *sublanguage* of<br>
trustworthy code.<br></blockquote></div>
</div></div>