picrin/contrib/20.r7rs/scheme/lazy.scm

49 lines
1.3 KiB
Scheme
Raw Normal View History

2014-07-19 01:15:53 -04:00
;;; Appendix A. Standard Libraries Lazy
(define-library (scheme lazy)
2016-06-02 12:44:03 -04:00
(import (scheme base))
;; type 'a <promise> = cached of 'a | chained of 'a promise | pending of () -> 'a promise
2014-07-19 01:15:53 -04:00
2014-08-05 22:33:07 -04:00
(define-record-type <promise>
2016-06-02 12:44:03 -04:00
(promise state value)
promise?
(state promise-state set-promise-state!)
(value promise-value set-promise-value!))
(define (make-promise obj)
(if (promise? obj)
obj
(promise 'cached obj)))
2014-07-19 01:15:53 -04:00
(define-syntax delay-force
(syntax-rules ()
((_ expr)
2016-06-02 12:44:03 -04:00
(promise (string->symbol "pending") (lambda () expr)))))
2014-07-19 01:15:53 -04:00
(define-syntax delay
(syntax-rules ()
((_ expr)
2016-06-02 12:44:03 -04:00
(delay-force (make-promise expr)))))
(define (force p)
(let ((v (promise-value p)))
(case (promise-state p)
((cached) v)
2016-06-02 13:42:48 -04:00
((chained) (let ()
(when (eq? 'cached (promise-state v))
(set-promise-state! p 'cached)
(set-promise-value! p (promise-value v)))
(force v)))
2016-06-02 12:44:03 -04:00
((pending) (let ((q (v)))
(when (eq? 'pending (promise-state p))
(set-promise-state! p 'chained)
(set-promise-value! p q))
(force p))))))
2014-07-19 01:15:53 -04:00
(export delay-force
delay
force
make-promise
promise?))