[plt-scheme] Multiple values
>From plt-scheme-bounces at list.cs.brown.edu Tue Feb 21 10:42:15 2006
>(...)
Whow! When I asked you for my first question, I did not know that this
will cause such a discussion!
BTW, I agree with:
>Just as a data point, I find multiple value returns very useful, I
>use them frequently, and they make me very happy.
>The example I use most often involves compiler passes. Many times in
>a compiler pass, for any particularly expression or statement, how
>you want to recombine the statement after recursing over the sub-
>parts depends on additional information about those subparts. For
>example, what variables they reference, the types of the
>subexpressions, whether or not one of the subexpressions called setjmp
>() or call/cc, and so on. Multiple value returns offer a very
>convenient way to pass the information back up the recursion stack
>without making the routines go exponential.
>You can, of course, pass the information back in other ways. Passing
>tuples back certainly works, but it's a pain; you're constantly
>allocating the tuple to return, immediately splitting it apart and
>then let-binding it anyways. It makes more sense to me to just return
>the values directly, and then let-bind them all at once with let-
>values. (...)
In addition, my opinion is that multiple values allows us to think about
producer/consumer, in a nicer way than CPS. If we consider the example I
already gave:
(define (butlast-and-last l)
(let ((first (car l))
(rest (cdr l)))
(if (null? rest)
(values '() first)
(call-with-values (lambda () (butlast-and-last rest))
(lambda (l0 last-0) (values (cons first l0) last-0))))))
it is very close to the same function using CPS, with a 2-argument
continuation:
(define (butlast-and-last-cps l k2)
(let ((first (car l))
(rest (cdr l)))
(if (null? rest)
(k2 '() first)
(butlast-and-last-cps rest (lambda (l0 last-0)
(k2 (cons first l0) last-0))))))
In fact, if I write "(values x y)", I think that the 2 values "x" and "y" will
be consumed later. If the "values" function is implemented by:
(define (values . arg-list)
(lambda (f) (apply f arg-list)))
this can mean that "arg-list" will be consumed later, when the formal argument
"f" is replaced by an "actual" function. This consumption is explicit in CPS,
implicit with multiple values. And "call-with-values", from my point of view,
is a bridge between a producer and consumer.
Back to my question about PLT Scheme's behaviour, I was surprised because I
thought that values' result may be viewed as a whole, that is, as a kind of
"packaged values" to be consumed later.
Yours sincerely,
J.-M. H.