More robust version of (scheme lazy)

This commit is contained in:
Justin Ethier 2020-09-09 22:28:00 -04:00
parent 4dda1b8a49
commit 5fbdc54628
2 changed files with 30 additions and 16 deletions

View file

@ -10,6 +10,7 @@ Features
Bug Fixes
- Improved `(scheme lazy)` to allow `force` and `make-promise` to accept an argument of any type. Improved representation of promises to more precisely differentiate them from other objects.
- Add type checking to record type accessor functions. We now raise an error if the passed object is of the wrong record type.
- Fix issues with expanding `cond-expand` expressions in libraries. Previously there would be issues with the expansion if the code needed to be within the context of a `begin`.

View file

@ -17,9 +17,19 @@
)
(begin
;; promise
;; ( tag value/obj )
(define *promise-tag* '(promise))
(define (promise? obj)
(and (pair? obj)
(eq? *promise-tag* (car obj))))
(define force
(lambda (object)
(object)))
(lambda (obj)
(if (promise? obj)
((cdr obj))
obj)))
(define-syntax delay
(er-macro-transformer
@ -32,20 +42,23 @@
`(make-promise (lambda () ,(cadr expr))))))
(define make-promise
(lambda (proc)
(let ((result-ready? #f)
(result #f))
(lambda ()
(if result-ready?
result
(let ((x (proc)))
(if result-ready?
(lambda (obj)
(if (promise? obj)
obj
(let ((result-ready? #f)
(result #f))
(cons
*promise-tag*
(lambda ()
(if result-ready?
result
(begin (set! result x)
(set! result-ready? #t)
result))))))))
(let ((x (if (procedure? obj)
(obj)
obj)))
(if result-ready?
result
(begin (set! result x)
(set! result-ready? #t)
result))))))))))
;; Not a very satisfying implementation, but would need to change
;; how promises are stored to do better
(define promise? procedure?)
))