<div dir="ltr"><div><div><div><div>I just sent a pull request : <a href="https://github.com/plt/racket/pull/727">https://github.com/plt/racket/pull/727</a><br><br></div>I added a few simple test cases, but the interesting thing is that running<br>
`./racket/bin/raco test pkgs/lazy` seems to pass even when I add a failing test case such as `(! (eq? 1 2)) => #t`.<br></div>That same test will fail as expected if I run it within drracket.<br><br></div>Thank you all for your time and help. (And thank you for creating such a nice community and toolset!)<br>
<br></div>-Luke<br><div><div><div><div><br></div></div></div></div><div class="gmail_extra"><br><br><br></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Fri, Jul 11, 2014 at 12:02 AM, Spencer Florence <span dir="ltr"><<a href="mailto:florence@northwestern.edu" target="_blank">florence@northwestern.edu</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">It looks like he has taken those down. But I'm sure he would email a copy if asked (the think is <a href="http://pl.barzilay.org/resources.html#classnotes" target="_blank">http://pl.barzilay.org/resources.html#classnotes</a> btw)</div>
<div class="HOEnZb"><div class="h5">
<div class="gmail_extra"><br><br><div class="gmail_quote">On Thu, Jul 10, 2014 at 8:42 PM, Matthias Felleisen <span dir="ltr"><<a href="mailto:matthias@ccs.neu.edu" target="_blank">matthias@ccs.neu.edu</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
There are also Eli's class notes. I don't have a URL handy but I am sure if you google "Eli Barzilay" and "course" you'll find his notes on the various levels of lazy (plus homework assignments :-) -- Matthias<br>
<div><div><br>
<br>
<br>
<br>
<br>
<br>
On Jul 10, 2014, at 6:41 PM, Stephen Chang wrote:<br>
<br>
> Actually, this is a bug, because the expression in a single-argument<br>
> values call is forced prematurely.<br>
><br>
> eg, This should not error:<br>
><br>
> -> (let-values ([(x) (values (error "a"))]) 1)<br>
> ; a [,bt for context]<br>
><br>
> Just like this does not error.<br>
><br>
> -> (let-values ([(x y) (values (error "a") (error "b"))]) 1)<br>
> 1<br>
><br>
> Lazy Racket is trying to preserve the (values x) == x from Racket, but<br>
> since LR's force is recursive, this is actually impossible without<br>
> breaking the semantics like it's doing now.<br>
><br>
> Luke, thanks for finding this. If you want to submit a pull request, I<br>
> will merge. (Just drop the first clause in the case-lambda entirely.)<br>
> Maybe some extra tests would be nice as well :) Otherwise if you dont<br>
> have time, let me know and I'll do it.<br>
><br>
>> Beyond the library documentation, does anyone know if there are any discussions or tutorials that go into the do's and don'ts of using #lang lazy ?<br>
><br>
> There isnt any. You can check out the Barzilay-Clements paper [1] to<br>
> learn about the motivation behind LR, but otherwise LR should have<br>
> "standard" lazy semantics.<br>
><br>
> [1]: <a href="http://digitalcommons.calpoly.edu/cgi/viewcontent.cgi?article=1047&context=csse_fac" target="_blank">http://digitalcommons.calpoly.edu/cgi/viewcontent.cgi?article=1047&context=csse_fac</a><br>
><br>
> On Thu, Jul 10, 2014 at 1:15 PM, Luke Whittlesey<br>
> <<a href="mailto:luke.whittlesey@gmail.com" target="_blank">luke.whittlesey@gmail.com</a>> wrote:<br>
>> Thank you for the in-depth analysis. Very interesting.<br>
>><br>
>> Following your reasoning, if I edit lazy.rkt and force `values` to use<br>
>> `multiple-values` for the single entry case, the example that was previously<br>
>> broken now works. (I just have no idea if this breaks something else in the<br>
>> process.)<br>
>><br>
>> at lazy.rkt line:223<br>
>> replace:<br>
>> (define* ~values<br>
>> (case-lambda [(x) x] [xs (multiple-values xs)]))<br>
>><br>
>> with:<br>
>> (define* ~values<br>
>> (case-lambda [(x) (multiple-values (list x))] [xs (multiple-values<br>
>> xs)]))<br>
>><br>
>><br>
>> I had assumed that a reference to an identifier was delayed, so thanks for<br>
>> showing that this is currently not the case.<br>
>><br>
>> Beyond the library documentation, does anyone know if there are any<br>
>> discussions or tutorials that go into the do's and don'ts of using #lang<br>
>> lazy ?<br>
>><br>
>> Thanks,<br>
>> Luke<br>
>><br>
>><br>
>> On Thu, Jul 10, 2014 at 6:24 AM, Matthew Flatt <<a href="mailto:mflatt@cs.utah.edu" target="_blank">mflatt@cs.utah.edu</a>> wrote:<br>
>>><br>
>>> I'm not sure whether to call it a bug or a limitation of `lazy`.<br>
>>><br>
>>> The `lazy` language doesn't delay a reference to an identifier. As a<br>
>>> result,<br>
>>><br>
>>> (define x y)<br>
>>> (define y (list 1))<br>
>>> (car x)<br>
>>><br>
>>> fails. The case could be made that the right-hand side of the definition<br>
>>> of `x` should have been a lazy reference to `y`, but that's not what<br>
>>> `lazy` currently does.<br>
>>><br>
>>> A problem with the current choice is that it interacts badly with `!`,<br>
>>> especially as used by `letrec-values`. The implementation of<br>
>>> `letrec-values` forces the right-hand side of a binding using `!` to<br>
>>> determine how many values it produces. That works ok when the<br>
>>> right-hand side is produced by `values` on more than one argument,<br>
>>> because `values` produces a special multiple-values result that leaves<br>
>>> its values unforced after `!`. When `values` get one argument, then it<br>
>>> just returns the argument.... and that's still ok for something like<br>
>>> `(values (list 1 (/ 0)))`, because the `(/ 0)` expression is lazy.<br>
>>><br>
>>> In your example, the implicit use of `!` for the right-hand side of the<br>
>>> A` binding produces `(! (list a B))`. That `B` is not itself treated as<br>
>>> a lazy expression, so forcing the list to be constructed causes `B` to<br>
>>> be evaluated early.<br>
>>><br>
>>> You can make the variable reference lazy by wrapping it with `~`:<br>
>>><br>
>>> (letrec-values ([(A) (values (list 'a (~ B)))]<br>
>>> [(B) (values (list 'b A))])<br>
>>> B)<br>
>>><br>
>>> Again, I don't know that you should have to do that, but it's how<br>
>>> `lazy` is defined at the moment.<br>
>>><br>
>>> At Mon, 7 Jul 2014 15:06:26 -0400, Luke Whittlesey wrote:<br>
>>>> Hello all,<br>
>>>> I've been playing around with creating circular lists (and learning<br>
>>>> racket<br>
>>>> which has been quite fun), but I'm stumped on why the lazy version of<br>
>>>> letrec-values is not producing a promise like the lazy version of letrec<br>
>>>> does. With the lazy letrec I can create circular lists, but with the<br>
>>>> lazy<br>
>>>> letrec-values I get #<undefined>. See the example below.<br>
>>>><br>
>>>> ;;;;;;;;;;;;;;;;; example code ;;;;;;;;;;;;;;;;;;;;;;;;;<br>
>>>> #lang lazy<br>
>>>><br>
>>>> ;; create a circular list using letrec (this works)<br>
>>>> (define example-working<br>
>>>> (letrec ([A (list 'a B)]<br>
>>>> [B (list 'b A)])<br>
>>>> B))<br>
>>>> (displayln "Working Example:")<br>
>>>> (displayln example-working)<br>
>>>> (displayln (!! example-working))<br>
>>>><br>
>>>> ; Prints...<br>
>>>> ;Working Example:<br>
>>>> ;(b #<promise:A>)<br>
>>>> ;#0=(b (a #0#))<br>
>>>><br>
>>>> ;; create a circular list using letrec-values (this is broken)<br>
>>>> (define example-broken<br>
>>>> (letrec-values ([(A) (values (list 'a B))]<br>
>>>> [(B) (values (list 'b A))])<br>
>>>> B))<br>
>>>> (displayln "Broken Example:")<br>
>>>> (displayln example-broken)<br>
>>>> (displayln (!! example-broken))<br>
>>>><br>
>>>> ; Prints<br>
>>>> ;Broken Example:<br>
>>>> ;(b (a #<undefined>))<br>
>>>> ;(b (a #<undefined>))<br>
>>>> ;;;;;;;;;;;;;;;;; end code ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<br>
>>>><br>
>>>> I realize that there are many different ways to generate circular lists,<br>
>>>> but why doesn't this work? Am I misunderstanding something or is this a<br>
>>>> bug?<br>
>>>><br>
>>>> Thanks,<br>
>>>> Luke<br>
>>>> ____________________<br>
>>>> Racket Users list:<br>
>>>> <a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/users</a><br>
>><br>
>><br>
>><br>
>> ____________________<br>
>> Racket Users list:<br>
>> <a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/users</a><br>
>><br>
> ____________________<br>
> Racket Users list:<br>
> <a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/users</a><br>
<br>
<br>
____________________<br>
Racket Users list:<br>
<a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/users</a><br>
</div></div></blockquote></div><br></div>
</div></div><br>____________________<br>
Racket Users list:<br>
<a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/users</a><br>
<br></blockquote></div><br></div>