[racket] lazy letrec-values
On Fri, Jul 11, 2014 at 1:41 AM, Stephen Chang <stchang at ccs.neu.edu> wrote:
> Actually, this is a bug, because the expression in a single-argument
> values call is forced prematurely.
IMO, the whole treatment of multiple values is a hack, for obvious
reasons. I was never happy with it, and debated whether the lazy
language should just drop them completely. Eventually, I kept them to
make it more similar to plain racket, and to be able to talk to non-lazy
code that may use them.
The issue here is a good example for why it's a hack, with no good
solution. IIUC, (I can't actually try it), the patch that was merged
fixes this:
> eg, This should not error:
>
> -> (let-values ([(x) (values (error "a"))]) 1)
> ; a [,bt for context]
>
> Just like this does not error.
>
> -> (let-values ([(x y) (values (error "a") (error "b"))]) 1)
> 1
and makes the former return 1, 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. 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!