I don't fully understand the use case... but have you looked at 'apply'?

> (define (sum4 a b c d)
    (+ a b c d))
> (apply sum4 1 2 (list 3 4))
10

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

> Thanks Jon, I appreciate the clear explanation.
>
> I'm using call-with-values in database code in order to turn a list into
> an acceptable set of bind parameters.  Here's an example:
>
> (query-exec conn "insert into foo (bar, baz) values ($1, $2)" (some-func))
>
> some-func returns a list, '("bob", "george").  query-exec throws an
> exception because it wants to see two elements for the bind parameters, not
> a list.  The solution I found was this:
>
> (call-with-values
>     (lambda () (apply values the-list))
>     (curry query-exec conn stmt))
>
> I know that I could have dug the parameters out with (car) and (cadr), but
> this seemed like it would be a common enough pattern that it was worth
> coming up with a standard answer that would work for any number of params.
>
> This is what got me thinking about how exactly (values) worked.
>
>
> On Fri, Jul 22, 2016 at 7:28 PM, Jon Zeppieri <zeppi...@gmail.com> wrote:
>
>>
>>
>> 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.
>

-- 
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