[racket] lazy letrec-values

From: Eli Barzilay (eli at barzilay.org)
Date: Mon Jul 14 07:09:45 EDT 2014

Sounds like this might lead to a way to implement MVs in a less messy
way: make MV-promises distinguishable, so you can get the number of
values (MV => length of the list of values, otherwise 1).  The problem
there is propagating the MV-ness when other promises wrap MV promises.
(The other direction would be to loop with "just enough force" but
this can lead to loops etc.)

On Mon, Jul 14, 2014 at 2:01 AM, Robby Findler
<robby at eecs.northwestern.edu> wrote:
> I think the examples suggest that you don't need to track the multiple
> values independently from each other but that you need to track the number
> of values separately from what the values actually are.
>
> Robby
>
>
> On Sunday, July 13, 2014, Matthias Felleisen <matthias at ccs.neu.edu> wrote:
>>
>>
>> Both issues are really about the idea that lazy languages
>> delay the right-hand side of definitions until the program
>> has determined what is in demand (and what isn't).
>>
>> 1. As you point out (define x y) thus imposes a large cost
>> on lazy programs. But that's the whole point of laziness.
>> It is less expressive than strictness and it is more expensive,
>> because everything happens at higher order type levels (not
>> type in the static sense).
>>
>> 2. This slogan also explains the 'values' problem. An MV
>> communication is a parallel flow of values. When this parallel
>> flow connects a right-hand side with a left-hand side, its
>> individual pieces must be delayed. If not, the delay may or
>> may not be necessary because the pieces may end up in a strict
>> position. So at least in principle the question of whether an
>> expression in a value position must be delayed is something to
>> be computed.
>>
>> A classical type system may or may not provide the answer.
>> A non-classical one will, by definition of the word 'type'.
>>
>> -- Matthias
>>
>>
>>
>>
>>
>>
>>
>>
>> On Jul 13, 2014, at 4:38 AM, Eli Barzilay wrote:
>>
>> > 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!
>> > ____________________
>> >  Racket Users list:
>> >  http://lists.racket-lang.org/users
>>
>> ____________________
>>   Racket Users list:
>>   http://lists.racket-lang.org/users



-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!

Posted on the users mailing list.