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