>> I still haven't seen a use case for smarts except localization,
>
> In any case, we can delay getting any expensive (in time and/or space)
> information about the error this way.
We could use promise objects for this. R5RS, R6RS, and R7RS all have
`delay` and `force`.
However, promises are not required to be disjoint type. R7RS gives a
`promise?` predicate but R5RS and R6RS don't.
It would be so nice to have:
;;----------------------------------------------------------------------
(define (disp . xs) (for-each display xs) (newline))
(define (plist-value-pair plist property)
(cond ((not (and (pair? plist) (pair? (cdr plist))))
#f)
((eq? property (car plist))
(cdr plist))
(else
(plist-value-pair (cddr plist) property))))
;;
(define-record-type foreign-status
(%make-foreign-status plist)
foreign-status?
(plist %foreign-status-plist))
(define (make-foreign-status . plist) (%make-foreign-status plist))
(define (foreign-status-ref st property)
(let ((pair (plist-value-pair (%foreign-status-plist st) property)))
(and pair
(begin (if (promise? (car pair))
(set-car! pair (force (car pair))))
(car pair)))))
;;
(define-syntax pp
(syntax-rules ()
((_ x) (begin (write 'x) (display " => ") (write x) (newline)))))
(let ((st (make-foreign-status 'code 4 'message (delay "Hello world"))))
(pp (foreign-status-ref st 'code))
(pp (foreign-status-ref st 'message)))
;; OUTPUT:
(foreign-status-ref st 'code) => 4
(foreign-status-ref st 'message) => "Hello world"