<div>Good memory!</div><div><br></div><div>This arguably moves the balance a bit in *favor* of the simpler</div><div>implementation, because this bug is a little less likely to come up in</div><div>practice than the existing bug PS. (Obviously it would be better to</div>



<div>eliminate both bugs.)</div><div><br></div><div>Is the compiler allowed to keep track of which functions return</div><div>multiple values? If so, it could recognize that the call to BLAH is</div><div>not a return value of FOO and compile FOO like this:</div>



<div><br></div><div>  function foo() {</div><div>      blah();</div><div>      SPILLOVER = null;</div><div>      return someRandomJsFunction();</div><div>  };</div><div><br></div><div>In other words, use it (where returning counts as a use) or lose it.</div>


<div><br></div><div>Daniel</div><div><br></div><br><div class="gmail_quote">
On Tue, Aug 28, 2012 at 8:20 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">



The counter-example to using a global variable as I remember it from<br>
the last discussion was this case:<br>
<div><br>
(defun blah ()<br>
    (values 1 2 3))<br>
<br>
  (defun foo ()<br>
    (blah)<br>
</div>    (some-random-js-function))<br>
<div><br>
  (defun bar ()<br>
    (multiple-value-bind (a b c) (foo)<br>
      (+ a b c)))<br>
<br>
</div>Now a call to bar returns 6, when it shouldn't. I think it might be<br>
possible to use another global variable as a flag that's set and<br>
checked by multiple-value aware PS functions, but I need to think<br>
about how to make it work.<br>
<span><font color="#888888"><br>
Vladimir<br>
</font></span><div><div><br>
On Tue, Aug 28, 2012 at 10:07 PM, Daniel Gackle <<a href="mailto:danielgackle@gmail.com" target="_blank">danielgackle@gmail.com</a>> wrote:<br>
> Those test failures make sense now - thanks. Also, this comment<br>
> reminded me of something:<br>
><br>
> < the callee.caller property for functions, which multiple value return<br>
> depends on ><br>
><br>
> I dislike our implementation for multiple value return. Stuffing the<br>
> values in callee.caller is complicated and doesn't feel right (I think<br>
> I may have been the one who came up with it; it was a bad idea), plus<br>
> it relies on one of the shakiest aspects if not of JS itself than<br>
> certainly of the JS implementations.<br>
><br>
> A simpler way occurred to me the other day and I'd like to know where<br>
> it breaks. The argument goes like this: since JS is single-threaded<br>
> and functions have to return synchronously, there can be only one<br>
> function return in play at any given time, therefore there can be only<br>
> one multiple-return-value list at any time, therefore why not just<br>
> store it in a global variable?<br>
><br>
> Say this variable is called *spillover*. Then this:<br>
><br>
>   (defun blah ()<br>
>     (values 1 2 3))<br>
><br>
>   (defun callblah ()<br>
>     (multiple-value-bind (a b c) (blah)<br>
>       (+ a b c)))<br>
><br>
> ...might compile to:<br>
><br>
>   function blah() {<br>
>       SPILLOVER = [2, 3];<br>
>       return 1;<br>
>   };<br>
>   function callblah() {<br>
>       var a = blah();<br>
>       var b = SPILLOVER[1];<br>
>       var c = SPILLOVER[2];<br>
>       return a + b + c;<br>
>   };<br>
><br>
> There might be complicating factors that would make the JS more<br>
> involved in practice, but I don't remember what they are.<br>
><br>
> Apart from being so much simpler, this implementation has two<br>
> advantages. First, it's "morally" better in Eugenia Cheng's sense<br>
> (<a href="http://cheng.staff.shef.ac.uk/morality/morality.pdf" target="_blank">http://cheng.staff.shef.ac.uk/morality/morality.pdf</a>). The multiple<br>
> return values don't belong to caller or callee, but to the call<br>
> itself. Caller and callee are functions that persist across many calls<br>
> and ought not to have information about a specific call attached to<br>
> them. That's why PS is forced to add ugly code to save the previous<br>
> value attached to callee and restore it using a try/finally at the end.<br>
><br>
> Second, it would fix a known problem. PS breaks when you have an<br>
> interloper like FOO here:<br>
><br>
>   (defun blah ()<br>
>     (values 1 2 3))<br>
><br>
>   (defun foo ()<br>
>     (blah))<br>
><br>
>   (defun bar ()<br>
>     (multiple-value-bind (a b c) (foo)<br>
>       (+ a b c)))<br>
><br>
> BAR should return 6, and does in CL, but in PS it returns 1, because<br>
> FOO doesn't return multiple values, so B and C are null and "1 + null +<br>
> null"<br>
> is 1 in JS. But the *spillover* hack would make BAR return 6.<br>
><br>
> Could we get away with this, or what am I missing?<br>
><br>
> Daniel<br>
><br>
><br>
> On Tue, Aug 28, 2012 at 6:00 PM, Vladimir Sedach <<a href="mailto:vsedach@gmail.com" target="_blank">vsedach@gmail.com</a>> wrote:<br>
>><br>
>> Hi Daniel,<br>
>><br>
>> Yes, those two failures in the eval test suite are expected.<br>
>> CL-JavaScript doesn't have the callee.caller property for functions,<br>
>> which multiple value return depends on. I wasn't sure where to comment<br>
>> those tests out, so I left them in to remind myself to add<br>
>> callee.caller to CL-JavaScript (I've already talked to Marijn<br>
>> Haverbeke about that).<br>
>><br>
>> Thank you,<br>
>> Vladimir<br>
>><br>
>> On Mon, Aug 27, 2012 at 11:58 PM, Daniel Gackle <<a href="mailto:danielgackle@gmail.com" target="_blank">danielgackle@gmail.com</a>><br>
>> wrote:<br>
>> > I've rebased my PS LOOP extensions [1] onto the latest commit<br>
>> > (7be9b45) and recompiled Skysheet. The generated JS looks fine. There<br>
>> > was one glitch that I'll report separately along with a workaround.<br>
>> > Before pushing the LOOP extensions onto master, though, I want to<br>
>> > update any relevant PS tests. Some will fail because the LOOP output<br>
>> > has changed quite a bit. Unfortunately I'm also seeing failures when I<br>
>> > run the tests in 7be9b45, which is prior to any of these LOOP<br>
>> > changes. I've pasted the output below [2]. It doesn't look like these<br>
>> > failures are related to work in ps-loop.lisp, so I'll just ignore them<br>
>> > for the time being, but Vladimir can you please comment on whether you<br>
>> > know about them or whether there's something unexpected going on?<br>
>> ><br>
>> > Daniel<br>
>> ><br>
>> > [1] These are the constructs FOR..OF and MAP..TO, plus a change to<br>
>> > FOR..ON, that I described in my email to this list on April 11.  They<br>
>> > are currently sitting in the "loop" branch. Rebasing them was<br>
>> > nontrivial because of Boris' additions to ps-loop.lisp, but it seems<br>
>> > to have all gone ok. Boris, if you're reading this, please look out for<br>
>> > any<br>
>> > regressions once I push these changes and let us know if you notice<br>
>> > anything.<br>
>> ><br>
>> > [2] Running output tests:<br>
>> ><br>
>> > ........................................................................................................................................................................................................................................................................................................................................................................................................................................<br>




>> >  Did 424 checks.<br>
>> >     Pass: 424 (100%)<br>
>> >     Skip: 0 ( 0%)<br>
>> >     Fail: 0 ( 0%)<br>
>> > Running package system tests:<br>
>> > .........<br>
>> >  Did 9 checks.<br>
>> >     Pass: 9 (100%)<br>
>> >     Skip: 0 ( 0%)<br>
>> >     Fail: 0 ( 0%)<br>
>> > Running CL-JavaScript eval tests:<br>
>> > ...........................f...............X......................<br>
>> >  Did 66 checks.<br>
>> >     Pass: 64 (96%)<br>
>> >     Skip: 0 ( 0%)<br>
>> >     Fail: 2 ( 3%)<br>
>> >  Failure Details:<br>
>> >  --------------------------------<br>
>> >  mv-return1 []:<br>
>> >       Unexpected Error: #<cl-js:js-condition #x30200155257D><br>
>> > [js] TypeError: undefined has no properties...<br>
>> >  --------------------------------<br>
>> >  --------------------------------<br>
>> >  dynamic-extent-function-return-values []:<br>
>> >       (funcall (if (typep #:g36204 'structure-object) #'equalp #'equal)<br>
>> > #:g36204 (jsarray '(1 2 3))) was NIL..<br>
>> >  --------------------------------<br>
>> ><br>
>> ><br>
>> > _______________________________________________<br>
>> > parenscript-devel mailing list<br>
>> > <a href="mailto:parenscript-devel@common-lisp.net" target="_blank">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>
>> ><br>
>><br>
>> _______________________________________________<br>
>> parenscript-devel mailing list<br>
>> <a href="mailto:parenscript-devel@common-lisp.net" target="_blank">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>
><br>
><br>
> Those test failures make sense now - thanks. Also, this comment<br>
> reminded me of something:<br>
><br>
> < the callee.caller property for functions, which multiple value return<br>
> depends on ><br>
><br>
> I dislike our implementation for multiple value return. Stuffing the<br>
> values in callee.caller is complicated and doesn't feel right (I think<br>
> I may have been the one who came up with it; it was a bad idea), plus<br>
> it relies on one of the shakiest aspects if not of JS itself than<br>
> certainly of the JS implementations.<br>
><br>
> A simpler way occurred to me the other day and I'd like to know where<br>
> it breaks. The argument goes like this: since JS is single-threaded<br>
> and functions have to return synchronously, there can be only one<br>
> function return in play at any given time, therefore there can be only<br>
> one multiple-return-value list at any time, therefore why not just<br>
> store it in a global variable?<br>
><br>
> Say this variable is called *spillover*. Then this:<br>
><br>
>   (defun blah ()<br>
>     (values 1 2 3))<br>
><br>
>   (defun callblah ()<br>
>     (multiple-value-bind (a b c) (blah)<br>
>       (+ a b c)))<br>
><br>
> ...might compile to:<br>
><br>
>   function blah() {<br>
>       SPILLOVER = [2, 3];<br>
>       return 1;<br>
>   };<br>
>   function callblah() {<br>
>       var a = blah();<br>
>       var b = SPILLOVER[1];<br>
>       var c = SPILLOVER[2];<br>
>       return a + b + c;<br>
>   };<br>
><br>
> There might be complicating factors that would make the JS more<br>
> involved in practice, but I don't remember what they are.<br>
><br>
> Apart from being so much simpler, this implementation has two<br>
> advantages. First, it's "morally" better in Eugenia Cheng's sense<br>
> (<a href="http://cheng.staff.shef.ac.uk/morality/morality.pdf" target="_blank">http://cheng.staff.shef.ac.uk/morality/morality.pdf</a>). The multiple<br>
> return values don't belong to caller or callee, but to the call<br>
> itself. Caller and callee are functions that persist across many calls<br>
> and ought not to have information about a specific call attached to<br>
> them. That's why PS is forced to add ugly code to save the previous<br>
> value and restore it using a try/finally at the end.<br>
><br>
> Second, it would fix a known problem. PS breaks when you introduce an<br>
> interloper like FOO here:<br>
><br>
>   (defun blah ()<br>
>     (values 1 2 3))<br>
><br>
>   (defun foo ()<br>
>     (blah))<br>
><br>
>   (defun bar ()<br>
>     (multiple-value-bind (a b c) (foo)<br>
>       (+ a b c)))<br>
><br>
> BAR should return 6, and does in CL, but in PS it returns 1, because<br>
> FOO doesn't return multiple values, so B and C are null and "1 + null +<br>
> null"<br>
> is 1 in JS. But the *spillover* hack would make BAR return 6.<br>
><br>
> Could we get away with this, or what am I missing?<br>
><br>
> Daniel<br>
><br>
><br>
> _______________________________________________<br>
> parenscript-devel mailing list<br>
> <a href="mailto:parenscript-devel@common-lisp.net" target="_blank">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>
><br>
<br>
_______________________________________________<br>
parenscript-devel mailing list<br>
<a href="mailto:parenscript-devel@common-lisp.net" target="_blank">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>