Apply values to a procedures

Hello,

I was in the need of applying a procedure to a result that return 3 values (x,y,z) to put this in a list.

I know this works:

(call-with-values (lambda () (values 1 2 3)) list)

but i find it not pleasant to wear the lamba () ... just because it is a convention? or perheaps there is something to understand that i do not see? so i decided to wrote this little macro in the way apply works:

(define-syntax apply-values
  (syntax-rules ()
    ((_ proc some-values) (call-with-values (lambda () some-values) proc))))

example:

(apply-values list (values 1 2 3))
'(1 2 3)

i think it is more simple and readable than the solution with call-with-values but i appreciate to know if i'm wrong or missing something and if it exist other syntax to do it?

Regards,

Damien

You can use (thunk body ...) instead of (lambda () ...) in this case.

It's not convention, though: it's explicitly used to delay evaluation. The call-with-values procedure expects a procedure of 0 arguments that produces multiple values, which are handed to the continuing procedure (second argument). Because Racket does not permit things like (add1 (values 1 2) 3), similarly (call-with-values (values 1 2 3) list) doesn't make sense.

The "extra notation" is not in the way so much with (call-with-values (thunk (f args)) list) (in other words, extracting the computation of the values to a named function; if it's nullary, simply (call-with-values f list)). Depending on your need you could also use define-values, let-values, match/values (and several other match cousins), or Qi.

3 Likes

if it exist other syntax to do it?

Warning: Self-promotion ahead

SRFI 210: Procedures and Syntax for Multiple Values has a lot of useful stuff to make working with multiple values cleaner. It's available for Racket in my extra-srfi-libs package. With it, your example could be written as

$ racket
Welcome to Racket v8.15 [cs].
> (require srfi/210)
> (list/mv (values 1 2 3))
'(1 2 3)
>

Documentation for list/mv:

(list/mv element1 … producer)

Syntax: Each element and producer can be any expression.

Semantics: A list/mv expression is evaluated as follows: Each element and producer are evaluated in an unspecified order. A list constructed from the single values of the elements and the multiple values of producer in that order is then returned.

2 Likes