-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathsuspension.rkt
32 lines (26 loc) · 1.06 KB
/
suspension.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
#lang racket
(provide
;; SYNTAX
#; (suspension e1 e2 ...)
;; creates a function of no arguments that always returns the result of the first call
;; any side effects of e1 e2 ... are only observable during the extent of the first call
suspend)
;; ---------------------------------------------------------------------------------------------------
(define-syntax-rule (suspend e1 e2 ...) (suspension (λ () e1 e2 ...) #false))
(struct suspension [thunk-x x]
#:transparent
#:mutable
#:property prop:procedure
(λ (self)
(define is-thunk (suspension-thunk-x self))
(when is-thunk
(set-suspension-x! self (is-thunk))
(set-suspension-thunk-x! self #false))
(suspension-x self)))
;; ---------------------------------------------------------------------------------------------------
(module+ test
(require rackunit)
(define s1 (suspend (displayln 'hello) 'x))
(check-equal? (let ((r1 (gensym)) [r2 (gensym)])
(list (with-output-to-string (λ () (set! r1 (s1)) (set! r2 (s1)))) r1 r2))
(list "hello\n" 'x 'x)))