[parenscript-devel] A simpler way to do multiple value return? (Was: PS test failures in 7be9b45)

Daniel Gackle danielgackle at gmail.com
Fri Sep 7 20:11:21 UTC 2012


OK, we're on the same wavelength. I'm glad you said "This issue
[i.e. passthrough] is orthogonal to how the multiple values are
passed" -- that's the same conclusion I've come to.

Now I wonder if we can fix the global variable (GV) design. Naive GV
had no way to suppress incorrect passthrough. But if it can be
corrected, a GV implementation would probably be simpler and more
efficient than foo.mv/arguments.callee.mv.

The foo.mv way suppresses passthrough by default and turns it on by
instrumenting tail calls. What about the inverse? Use a GV to enable
passthrough by default and turn it off by instrumenting *non* tail
calls. Something like:

  (defun foo (x y z)
    (values x y z))

  (defun baz ()
    (foo))

  (defun bar ()
    (foo)
    (baz))

  var EXTRAS = null; // global variable for MV returns

  function foo(x, y, z) {
    EXTRAS = [y, z];
    return x;
  }

  function baz() {
    return foo(); // passthrough enabled by default
  }

  function bar () {
    foo();
    EXTRAS = null; // instrumentation to suppress passthrough
    return baz(); // transitive passthrough is free
  }

You'd want "EXTRAS = null" after each MULTIPLE-VALUE-BIND as well, but
maybe you get this for free since the function call in a
MULTIPLE-VALUE-BIND is by definition not a tail call.

We can summarize this proposal similarly to the other one:

  1. Pass multiple values using a global variable
  2. Instrument every non-tail call.

It may still be too naive but it at least fixes the examples that
broke GV earlier in the thread. So, is there an example that works in
foo.mv but fails in GV as described above?

Dan

p.s. I also wonder if the recursion difficulty disappears now that we
understand passthrough better. The example was:

  (defun foo (x)
    (if (= x 1)
        (values 1 2)
        (1+ (foo (1- x)))))

In both the GV and foo.mv designs, shouldn't foo(2) do the right thing
now? That recursion is a non-tail call, so GV would suppress MV
passthrough and foo.mv wouldn't enable it.


On Fri, Sep 7, 2012 at 12:46 PM, Vladimir Sedach <vsedach at gmail.com> wrote:

> Hi Dan,
>
> > The only easy implementation I can think of is to mv-instrument every
> > tail call in the program, but that is surely overkill.
>
> Yes, that's currently the only way I see to do it. This issue is
> orthogonal to how the multiple values are passed - in principle I
> could have implemented the multiple value passing instrumentation
> right after adding the return instrumentation code, but it didn't
> occur to me at the time.
>
> So to clarify, my proposal has two separate components:
> 1. Pass multiple values on the callee function object
> 2. Instrument every tail call
>
> Vladimir
>
> _______________________________________________
> parenscript-devel mailing list
> parenscript-devel at common-lisp.net
> http://lists.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/20120907/70639610/attachment.html>


More information about the parenscript-devel mailing list