[racket] Splicing `values' in-place

From: Laurent (laurent.orseau at gmail.com)
Date: Thu Jul 11 11:13:02 EDT 2013

On Thu, Jul 11, 2013 at 4:42 PM, Matthias Felleisen <matthias at ccs.neu.edu>wrote:

>
> Your uses of values are covered in apply/map/append/list trickeries.


Yes, for example
(+ (values 1 2) (values 3 4))
would need to be written
(apply + (append (call-with-values (lambda()(values 1 2)) list)
(call-with-values (lambda()(values 3 4)) list)))
which is really cumbersome.

However, actually, if `values' were exactly `list' (e.g., with
`define-list' instead of `define-values'), I think it would be more usable
than what it is now.
At least there would be no need to convert values to lists, use list
operations, then convert lists back to values.
The above example would be written:
(apply + (append (list 1 2) (list 3 4)))
which is already much better.

But then, compared to splicing values, every call would need to be like
this one, using `apply' and `append' everywhere, which is also quite
cumbersome (and not elegant).
And `(list 1)' is not equivalent to `1'.

On the contrary, with splicing values, `(values 1)' is equivalent to `1',
as it should be.

I guess Scribble would be happy to use such splicing values.


> Using values might be more elegant, but yes, it's currently not possible.
>

And I think it's the kind of elegance that makes the distinction between
usable and not.
(Since most languages are Turing-complete, features are not a matter of
whether something can be done but of how much effort it takes to do
something, but you are well aware of that, and Racket is very good at that,
most of the time. I just wish some of the core designs would allow for a
bit more flexibility.)

Laurent


>
>
>
> On Jul 11, 2013, at 8:56 AM, Laurent wrote:
>
> > In some postfix languages, if a procedure returns multiple values, these
> values can be used directly as multiple arguments to another procedure
> call, i.e., they are "spliced" in the latter call.
> > In an extended Racket, this would look like this:
> >
> > (+ (values 1 2) (values 3 4))
> > would be equivalent to
> > (+ 1 2 3 4)
> >
> > (map values '(0 1 2) '(a b c))
> > would return
> > '(0 a 1 b 2 c)
> >
> > (call-with-values (lambda()(my-proc ....)) list)
> > would simply be
> > (list (my-proc ....))
> >
> > (values (values 1 2) (values 'a 'b))
> > would be equivalent to
> > (values 1 2 'a 'b)
> >
> > Correct me if I'm wrong, but I think all the cases where this feature
> should be useful currently throws an error, so it would probably break only
> very little.
> >
> > Such a missing feature tickles me from time to time, and I often find
> that Racket `values' system is too cumbersome to be used more often, i.e.,
> you need to go through stages of `call-with-values', 'let/define-values',
> `(apply values ....)', etc. and I often find myself not wanting to go down
> this road.
> >
> > IMO, `values' is *meant* to be the way I describe above: `values' is
> exactly like `list', except than instead of encapsulating the values in a
> container, it splices them in-place.
> >
> > Do you see some disadvantages of using values this way?
> > For example, in some occasions, for things like
> > (define (foo x) (values x x))
> > (map + (foo '(1 2 3)))
> > it may be more difficult to infer that there are actually 2 lists in the
> map, but to me it's just a matter of style/taste/comments/documentation,
> not a matter of feature.
> >
> > Laurent
> > ____________________
> >  Racket Users list:
> >  http://lists.racket-lang.org/users
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20130711/cc40e003/attachment.html>

Posted on the users mailing list.