# [plt-scheme] Multiple values

I'm not certain that butlast-and-last is an "actual" example. If you
stick to lists, then the following works and is much faster, too (using
MzScheme on a short list, anyway)...
(define (cleaver l)
(let ((reversed (reverse l)))
(list (reverse (cdr reversed)) ;; or values
(car reversed))))
rac
On Feb 20, 2006, at 4:03 PM, hufflen at lifc.univ-fcomte.fr wrote:
>>* At Mon, 20 Feb 2006 13:06:08 -0800, Gregory Woodhouse wrote:
*>>* (...)
*>*
*>>* (...) So, if you were to think of this slightly
*>>* more generally, you might compare this:
*>>*
*>>* (let ([x (compute-x ...)]
*>>* [y (compute-y ...)])
*>>* (+ x y))
*>>*
*>>* to this:
*>>*
*>>* (let-values ([(x y) (compute-both-x-and-y ...)])
*>>* (+ x y))
*>*
*>* Yes. More generally, I often use multiple values because they allow
*>* multiple computation. For an "actual" example, let us consider a
*>* non-empty linear list. Let us assume that we have to get, on the one
*>* hand, the list but its last element, on the other hand, its last
*>* element. You can write two functions for these two purposes, but they
*>* would go along the list twice. Multiple values allow to get the two
*>* results in one pass:
*>*
*>* (define (butlast-and-last l)
*>* ;; "l" is supposed to be non-empty, returns two values: a linear
*>* list
*>* with
*>* ;; all the elements of "l" but the last one, and the last one.
*>* (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))))))
*>*
*>* Yours sincerely,
*>*
*>* J.-M. H.
*>*
*>* _________________________________________________
*>* For list-related administrative tasks:
*>* http://list.cs.brown.edu/mailman/listinfo/plt-scheme
*