[racket] how to use 'lazy' from racket/promise
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!