Subject: Re: SBCL is now faster than Java, as fast as Ocaml, and getting better
From: rpw3@rpw3.org (Rob Warnock)
Date: Thu, 17 Jul 2008 04:13:27 -0500
Newsgroups: comp.lang.lisp
Message-ID: <XLGdnZnS6_WqkOLVnZ2dnUVZ_sPinZ2d@speakeasy.net>
Kenny  <kentilton@gmail.com> wrote:
+---------------
| Rob Warnock wrote:
| > Kenny  <kentilton@gmail.com> wrote:
| > +---------------
| > | I got it! Every form returning a value is necessary for us to have the 
| > | functional paradigm /available/ to us, and it is a fine paradigm, we 
| > | just do not want to be enslaved to never changing state.
| > +---------------
| > 
| > And it is precisely this lack of "enslavement" which motivated
| > CL to *silently ignore* excess return values and provide NIL
| > for excess caller requests for them, whereas the Scheme standards
| > [and most Scheme implementations] blow chunks at any caller/callee
| > mismatch on number of values.
| 
| Omigod!!! Why wasn't I told?? Throw me a bone, people!
| 
| Somewhat more seriously, duh-yamn, I never heard this one before.
| So in Scheme I would die asking floor to give me the floor if I
| did not pretend to be interested in the remainder.
+---------------

Yup. As pointed out in a parallel reply, in Scheme FLOOR is *just*
FLOOR and MOD is *just* MOD [no REM per se]. However, R6RS introduced
a new standard library procedure [not available in R5RS or earlier],
DIV-AND-MOD, which returns two values, see:

    http://www.r6rs.org/final/html/r6rs/r6rs-Z-H-14.html#node_sec_11.7.4.3
    11.7.4.3  Arithmetic operations

But caller/callee values still must exactly match, see:

    http://www.r6rs.org/final/html/r6rs/r6rs-Z-H-8.html#node_sec_5.8
    5.8  Multiple return values

and:

    http://www.r6rs.org/final/html/r6rs/r6rs-Z-H-14.html#node_sec_11.15
    11.15  Control features
    ...
    The continuations of all non-final expressions within a sequence
    of expressions, such as in lambda, begin, let, let*, letrec, letrec*,
    let-values, let*-values, case, and cond forms, usually take an
    arbitrary number of values.

[That is, the places in "bodies" [implicit PROGNs, in CL] that would
throw away *a* value will also throw away any number of values.]

    Except for these and the continuations created by call-with-values,
    let-values, and let*-values, continuations implicitly accepting a
    single value, such as the continuations of <operator> and <operand>s
    of procedure calls or the <test> expressions in conditionals, take
    exactly one value. The effect of passing an inappropriate number of
    values to such a continuation is undefined. 

    (call-with-values producer consumer)    procedure 

    Producer must be a procedure and should accept zero arguments.
    Consumer must be a procedure and should accept as many values as
    producer returns.  ...
    ...
    Implementation responsibilities: After producer returns, the
    implementation must check that consumer accepts as many values
    as consumer has returned.

So there you have it!  [Just one more reason I switched to CL, b.t.w.]

To be fair(?), the one obvious escape-hatch *is* supported, in that a
procedure with a single &REST arg [in Scheme, (LAMBDA REST BODY...)]
can be used as a consumer that will will accept any number of values.
And thus one could define a near-equivalent of CL's MULTIPLE-VALUE-LIST
in Scheme this way:

    (define (multiple-value-list producer)   ; Note: PRODUCER must be a thunk
      (call-with-values producer (lambda rest rest)))

or more simply:

    (define (multiple-value-list producer)
      (call-with-values producer list))   ; Assumes LIST has not been rebound


-Rob

p.s. Allowing a Scheme MULTIPLE-VALUE-LIST take a function-call
FORM arg [as in CL] instead of a PRODUCER thunk arg would require
MULTIPLE-VALUE-LIST to be a macro.

-----
Rob Warnock			<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607