10 hours ago, Ryan Culpepper wrote: > See SRFI-45 (http://srfi.schemers.org/srfi-45/srfi-45.html) for a > discussion of why lazy is necessary (ie, why force and delay are not > sufficient in practice). > > Racket's lazy might (?) be slightly different from the one discussed > there, though. See this post by Eli for why: > http://srfi.schemers.org/srfi-45/post-mail-archive/msg00013.html > (according to comments in racket/private/promise.rkt).
There are several differences between what we have and what's specified in the srfi: * Our implementation uses structs instead of the usual (tagged) list hack. * `force' can work on any value -- if it's not a promise, it just returns the value as is. * `lazy' can be used with any input value, so (lazy 3) works whereas in the srfi you must first "lift" the value into a promise: (lazy (delay 3)). (But we also have (lazy (delay 3)) work the same as in the srfi, of course.) * Because of the above, we don't really need `eager'. We do have `delay/strict' though, but that's because it's useful to have a bunch of different kinds of promises with the same interface. * To make things a little faster, our `lazy' doesn't handle multiple values, only `delay' does. However, `lazy' can be wrapped around a multiple-value promise as in (force (lazy (delay (values 1 2 3)))). IIRC, the srfi has nothing about multiple values. * Both our `delay' and `lazy' (and other delays) allow multiple expressions in their body. * Our promises properly catch and re-throw exceptions. For example: -> (define c -1) -> (define p (delay (set! c (add1 c)) (/ 1 c))) -> (force p) ; /: division by zero [,bt for context] -> (force p) ; /: division by zero [,bt for context] -- ((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