On Fri, Jul 11, 2014 at 1:41 AM, Stephen Chang <stch...@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! ____________________ Racket Users list: http://lists.racket-lang.org/users