[racket] Named let and multiple values

From: Carl Eastlund (cce at ccs.neu.edu)
Date: Thu Jul 28 00:36:40 EDT 2011

I can think of one possible better way, assuming the multiple values
in an actual program are generated by some other function.  Obviously
with (loop (values (add1 a) b)) you can simply write (loop (add1 a)
b).  But if you had (loop (f a b)), where f returns two values, you
can write the following:

(define (f a b) (values (add1 a) b)) ;; duplicating the previous behavior

(let loop ([a 1] [b 2])
  (if (= a b)
     ((compose loop f) a b)))

The result of compose will pass a and b to f, and its two resulting
values to loop.

Carl Eastlund

On Thu, Jul 28, 2011 at 12:28 AM, Justin Zamora <justin at zamora.com> wrote:
> I'd like to be able to write something like this:
> (let loop ([a 1] [b 2])
>   (if (= a b)
>      3
>      (loop (values (add1 a) b))))
> This would match the way for/fold works with more than one value.
> However, I get a message, "context expected 1 value, received 2
> values: 2 2", which makes sense given the expansion of named let, but
> it would be nice if this worked.  Using (call-with-values (lambda ()
> (values (add1 a) b)) loop) works, but that seems to defeat the point
> of using a named-let form for clarity.  I could also use let-values to
> deconstruct the values and pass them individually to the loop, but
> that hardly seems better.  Is there a better way?
> Justin

Posted on the users mailing list.