[parenscript-devel] Multiple value calls

Daniel Gackle danielgackle at gmail.com
Sun Nov 1 17:50:11 UTC 2009


It might help to use a PS special variable and make MULTIPLE-VALUE-BIND
responsible for cleanup.

(ps (defvar *mv* undefined))

(defpsmacro values (main &rest additional)
  (with-ps-gensyms (mv)
    `(let ((,mv (list , at additional)))
       (when (defined *mv*)
         (setf *mv* ,mv))
       (return ,main))))

(defpsmacro multiple-value-bind (vars expr &body body)
  `(let ((*mv* '()))
     (let ((,(car vars) ,expr))
      (destructuring-bind ,(cdr vars) *mv*
        , at body))))

This works in the obvious cases. I'm not sure it handles Red's scenarios.
Red, can you supply an example where this breaks?

Daniel

p.s. I took the easy way out of making VALUES always prepend RETURN, but
once Vladimir bestows implicit RETURN upon us we can take that out ;)


On Sat, Oct 31, 2009 at 9:53 PM, Red Daly <reddaly at gmail.com> wrote:

> I apologize for sending the first half of this email in error earlier:
>
> On Sat, Oct 31, 2009 at 8:35 PM, Red Daly <reddaly at gmail.com> wrote:
>
>> Hi Parenscripters,
>>
>> As far as I can tell, multiple-value function calls are a unique feature
>> of lisp.  I would like the ability to perform multiple-value calls in
>> Parenscript but I don't know if a sane solution exists or not.
>>
>> Can anyone come up with a scheme for returning multiple values that
>> translates well to Javascript?  Ideally such a scheme would not introduce
>> much overhead for usual functions that do not use or return multiple values
>> (though perhaps setting some sort of global MV flag might be inexpensive
>> enough).  Functions that return multiple values should also only appear to
>> return a single value when called by a function that expects only one return
>> value (including native javascript functions).
>>
>> (defun paren-mv-returner ()
>>   (return (values 1 2 3)))
>>
>> =>
>>
>>
>> function parenMvReturner() {
>>    /* do some magic with the values 2 and 3 */
>>    return 1;
>> }
>>
>> // one  implementation might be
>> var mv = undefined;
>>
>> function parenMvReturner() {
>>    mv = [2, 3];
>>    return 1;
>> }
>>
>> // this scheme needs to adjust the return statement of every function so
>> it might not be sufficient
>> // consider this other function
>>
>> function parenMySingleReturner () {
>>    var x = parenMvReturner();
>>
> return x;
> }
>
> // parenMySingleReturner() will appear to return multiple values unless it
> modifies the mv value itself
>
> // correction:
>
> function parenMySingleReturner () {
>    var x = parenMvReturner();
>    mv = null;
>    return x;
> }
>
> But it seems like this solution will fall apart for calls to native
> Javascript functions over which we have no control.  If we pass a
> multiple-value returning function as an argument to a native function, the
> native function will not perform the necessary mv-nulling when it returns.
>
> someForeignJavascriptFunction( someMVReturningFunction)
>
> will return whatever the someForeignJavascriptFunction should return, but
> it will also appear to return the other values that someMVReturningFunction
> set in the mv variable, since someForeignJavascriptFunction performs no
> cleanup.
>
> Maybe this limitation can be avoided by having an mv-returning function A
> set a global variable "mvFunctionReturner" equal to the function A and a
> mv-receiver can check that mvFunctionReturner is set according to the
> function it called expecting multiple values.  Does this scheme miss any
> cases?
>
> Anyway I have thought a little bit about this and I thought I would pass it
> off to the rest of the Parenscripters as a thought experiment.  Assume you
> can do a lot more semantic analysis than Parenscript currently does and
> transform the compiled source however you want.  But any compiled functions
> must still be able to be treated as normal Javascript functions and all and
> only functions that should return multiple values appear to return them.
>
> Cheers,
> Red
>
> _______________________________________________
> parenscript-devel mailing list
> parenscript-devel at common-lisp.net
> http://common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/parenscript-devel/attachments/20091101/f9b6c1f0/attachment.html>


More information about the parenscript-devel mailing list