/
promise.rkt
39 lines (30 loc) · 937 Bytes
/
promise.rkt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#lang typed/racket/base
(require (for-syntax racket/base))
;; Working around what appears to be a bug in Typed Racket
;; by implementing my own promises.
(provide my-delay my-force MyPromise)
(define-struct: Sentinel ())
(define-struct: (a) MyPromise ([forced? : Boolean]
[thunk : (-> a)]
[val : (U Sentinel a)])
#:mutable)
(define-syntax (my-delay stx)
(syntax-case stx ()
[(_ expr ...)
(syntax/loc stx
(make-MyPromise #f
(lambda () expr ...)
(make-Sentinel)))]))
(: my-force (All (a) (MyPromise a) -> a))
(define (my-force a-promise)
(cond
[(MyPromise-forced? a-promise)
(define val (MyPromise-val a-promise))
(if (Sentinel? val)
(error 'force "Impossible")
val)]
[else
(define val ((MyPromise-thunk a-promise)))
(set-MyPromise-val! a-promise val)
(set-MyPromise-forced?! a-promise #t)
val]))