<div>I don't understand this bit. Can you give an example?</div><div><br></div><div>> So this wouldn't work if you call a JS function expecting multiple</div><div>> values, and that JS function happens to call a PS function that</div>

<div>> wants to return multiple values.</div><div><br></div><div>In any case, interoperability with non-PS programs is a separate</div><div>issue- as far as I can tell, neither the GV nor <a href="http://foo.mv">foo.mv</a> designs can</div>

<div>achieve it.</div><div><br></div><div>> I see a problem in that you'd have to instrument not just return</div><div>> statments, but any kind of control flow that goes up the stack - so</div><div>> you'd have to put the suppression code at the end of every function</div>

<div>> definition, and also wrap throws.</div><div><br></div><div>I haven't come up with any examples of this yet and would like to see</div><div>one. It seems the question is, how might the GV design fail to clean</div>

<div>up dangling MV state? There are three ways for MV state to flow in GV:</div><div><br></div><div>  (1) non-tail calls that clear MV;</div><div>  (2) non-tail calls that bind MV and then clear it;</div><div>  (3) tail calls that let MV pass through.</div>

<div><br></div><div>The only instrumentation that GV adds is to clear MV in cases (1) and</div><div>(2). It doesn't instrument return statements. I think one can show</div><div>that (1) and (2) can't fail in a way that leaves any dangling MV.</div>

<div>Consider (2). The JS looks something like:</div><div><br></div><div>  var temp = firstResult();</div><div>  MV = [secondResult()];</div><div>  return temp;</div><div><br></div><div>  // in caller</div><div>  var blah = undefined;</div>

<div>  if (MV) {</div><div>    blah = MV[0];</div><div>  }</div><div>  MV = null;</div><div><br></div><div>There's no way for any of this code to fail except in firstResult() or</div><div>secondResult(), in which case MV never gets assigned and no state can</div>

<div>dangle. That answers case (2). For case (1) just remove the code that </div><div>binds MV.</div><div><br></div><div>That leaves (3), tail call passthrough. Can this case fail? I was</div><div>going to say it could, but now I'm not sure. Consider this example:</div>

<div><br></div><div>  (defun foo (x y)</div><div>    (blah1)</div><div>    (values x y))</div><div><br></div><div>  (defun baz ()</div><div>    (blah2)</div><div>    (foo))</div><div><br></div><div>  (defun bar ()</div><div>

    (blah3)</div><div>    (multiple-value-bind (a b) (baz)</div><div>      (blah4 a b)))</div><div><br></div><div>If an error is thrown from blah1, blah2, or blah3, no MV is assigned.</div><div>If an error is thrown from blah4, MV has already been cleared.</div>

<div><br></div><div>The argument is that the tail-call-ness of (FOO) inside BAZ doesn't</div><div>leave any space for failures to "squeeze in". One example isn't the</div><div>general case, obviously, but having gotten this far I'd be intrigued</div>

<div>to see an example of where GV can leave dangling state (apart from</div><div>interop with non-PS code, which as I said I think both designs fail at, </div><div>and which I suspect is impossible to do perfectly).</div>

<div><br></div><div>It's worth noting that <a href="http://foo.mv">foo.mv</a> might have a problem with errors too:</div><div><br></div><div>  <a href="http://foo.mv">foo.mv</a> = <a href="http://arguments.callee.mv">arguments.callee.mv</a>;</div>

<div>  var result = foo();</div><div>  delete <a href="http://foo.mv">foo.mv</a>;</div><div>  return result;</div><div><br></div><div>If foo() throws an error, there is a dangling <a href="http://foo.mv">foo.mv</a>. Might that be</div>

<div>harmless? If it isn't, you need something like:</div><div><br></div><div>  <a href="http://foo.mv">foo.mv</a> = <a href="http://arguments.callee.mv">arguments.callee.mv</a>;</div><div>  try {</div><div>    return foo();</div>

<div>  } finally {</div><div>    delete <a href="http://foo.mv">foo.mv</a>;</div><div>  }</div><div><br></div><div>... around every tail call in the program. The possible performance</div><div>hit is worrisome. That's on top of the possible performance hit of</div>

<div><a href="http://arguments.callee.mv">arguments.callee.mv</a>, which is the kind of thing that causes V8 to turn</div><div>off optimizations.</div><div><br></div><div>Daniel</div><div><br></div><br><div class="gmail_quote">

On Fri, Sep 7, 2012 at 7:00 PM, Vladimir Sedach <span dir="ltr"><<a href="mailto:vsedach@gmail.com" target="_blank">vsedach@gmail.com</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">> You'd want "EXTRAS = null" after each MULTIPLE-VALUE-BIND as well, but<br>
> maybe you get this for free since the function call in a<br>
> MULTIPLE-VALUE-BIND is by definition not a tail call.<br>
><br>
> We can summarize this proposal similarly to the other one:<br>
><br>
>   1. Pass multiple values using a global variable<br>
>   2. Instrument every non-tail call.<br>
><br>
> It may still be too naive but it at least fixes the examples that<br>
> broke GV earlier in the thread. So, is there an example that works in<br>
> <a href="http://foo.mv" target="_blank">foo.mv</a> but fails in GV as described above?<br>
<br>
</div>I see a problem in that you'd have to instrument not just return<br>
statments, but any kind of control flow that goes up the stack - so<br>
you'd have to put the suppression code at the end of every function<br>
definition, and also wrap throws. So this wouldn't work if you call a<br>
JS function expecting multiple values, and that JS function happens to<br>
call a PS function that wants to return multiple values.<br>
<div class="im"><br>
> p.s. I also wonder if the recursion difficulty disappears now that we<br>
> understand passthrough better. The example was:<br>
><br>
>   (defun foo (x)<br>
>     (if (= x 1)<br>
>         (values 1 2)<br>
>         (1+ (foo (1- x)))))<br>
><br>
> In both the GV and <a href="http://foo.mv" target="_blank">foo.mv</a> designs, shouldn't foo(2) do the right thing<br>
> now? That recursion is a non-tail call, so GV would suppress MV<br>
> passthrough and <a href="http://foo.mv" target="_blank">foo.mv</a> wouldn't enable it.<br>
<br>
</div>You're right. Good point.<br>
<div class="HOEnZb"><div class="h5"><br>
Vladimir<br>
<br>
_______________________________________________<br>
parenscript-devel mailing list<br>
<a href="mailto:parenscript-devel@common-lisp.net">parenscript-devel@common-lisp.net</a><br>
<a href="http://lists.common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel" target="_blank">http://lists.common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel</a><br>
</div></div></blockquote></div><br>