On Fri, Jul 22, 2016 at 6:30 PM, David Storrs <david.sto...@gmail.com>
wrote:

>
> The best mental model I've been able to come up with is that (values)
> returns its results vertically but most functions expect to get them
> horizontally and will die if there are parallel lines of uncollected
> values. Under this model (call-with-values) collects values from the Y
> axis and pivots them back onto the X axis for consumption by regular
> functions. This feels like a fragile analogy though.  Would someone
> please fill me in on how it actually works?
>
>

When you do:

   (values ...)

in a DrRacket window, it does list the values vertically, but that's
probably not a very useful way to think about what `values` is.  You can
think of `values` as a constructor of a second-class tuple. The fact that
the resultant tuple is "second-class" is very important here. You can't
give a name to this tuple. For example,

   (define foo (values 1 2 3))

is illegal.  You can't pass it as an argument to a procedure:

   (list (values 1 2 3))

is likewise illegal. There is, in fact, very little you can do with this
tuple other than let `call-with-values` unpack it.

`call-with-values` is special (like call-with-continuation is special). Its
first argument, a zero-arity procedure, produces a values which are then
passed *as separate arguments* -- not as a second-class tuple -- to its
second argument. That's what `call-with-values` does: it translates this
second-class tuple into separate procedure arguments.

`call-with-values` is rarely used directly. It's far more common to use
`define-values` or `let-values` (or one of its variants). For example,
although you can't do:

   (define foo (values 1 2 3))

You can do:

   (define-values (a b c) (values 1 2 3))

There is one special case to keep in mind: a unary use of `values`, e.g.:

   (values 1)

is exactly equivalent to its argument. That is, (values 1) *is exactly* 1.
That's not true for any other arity of `values`. (This is also how
*first*-class tuples in ML behave.)

For my own part, I'm not a big fan of `values` and `call-with-values`.
Their use is for returning multiple values from a procedure -- which you
can also do by returning a first-class, composite piece of data, like a
vector or a list. The one advantage of second-class tuples is that, because
there's so little you can do
with them, they're easier to give optimized representations.

- Jon

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to