[racket] lazy letrec-values

From: Stephen Chang (stchang at ccs.neu.edu)
Date: Mon Jul 14 13:09:01 EDT 2014

The problem was that the values constructor in Lazy Racket had two
different semantics, depending on the number of arguments, but the
extractors (ie let-values and friends) only handled the latter. We
should decide on one consistent behavior, mv's should either behave
like:

1) tuples in a lazy language, or
2) racket values

LR mv's already mostly behave like #1, and not like racket values. For
example, (values 1 2) returns a multiple-values struct instance that
can be passed around before extracting the values, something you
cannot do in Racket. So it seems odd to me to enforce the Racket-like
values behavior for only single-value values. The patch just makes all
mv's consistently have the #1 behavior.

> but now you get a different kind of
> breakage where
>
>   (let-values ([(x) (values (error "a"))]) 1)
>   (let-values ([(x)         (error "a") ]) 1)
>
> are not the same.

If we want behavior #1, then these should not be the same, since you
have to force down "one level" to get the shape, as Robby mentioned.

If we want #2, the Racket-values behavior, then it seems to me like
the right thing to do is to use !values everywhere instead of !. I
understand not wanting to do so since it adds an extra check for every
force, but since lazy Racket is not really performant enough for
practical use, maybe this doesn't matter?



> More than that, the hack of dealing with multiple
> values is at such a (bad) level, that it's possible that the patch would
> break code that assumes that `E' is equivalent to (values E).
>
> A more proper way to deal with `*-values' constructs would be for the
> macro to treat a case of != 0 values differently from a single value, so
> the force that breaks the above is not done.  That is, this kind of
> change would make these two:
>
>     > (let-values ([(x) (values (error "poof"))]) 1)
>     1 ; `values' doesn't wrap, but (x) means no !-ing
>     > (let-values ([(x y) (values (error "poof"))]) 1)
>     poof ; since now there are (x y) so the macro !s the RHS
>
> This is clearly not great either, but I think that overall it would be
> more consistent.  (But of course it's not a 10-second fix.)
>
> (A much better way to deal with MVs is to have "TLR" (= TR+LR).)
>
> --
>           ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
>                     http://barzilay.org/                   Maze is Life!

Posted on the users mailing list.