[racket] lazy letrec-values

From: Matthias Felleisen (matthias at ccs.neu.edu)
Date: Mon Jul 14 16:37:01 EDT 2014

I would much prefer option 2. We don't want to be needlessly different than R. 

One question we may wish to consider is what the semantic relationship is between LR and R. This one was easy for TR and R. Here, I am not sure what to say (exactly) but figuring this out, would help a lot getting a handle on LR's design principles. 

-- Matthias





On Jul 14, 2014, at 1:09 PM, Stephen Chang <stchang at ccs.neu.edu> wrote:

> 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!
> ____________________
>  Racket Users list:
>  http://lists.racket-lang.org/users



Posted on the users mailing list.