Tagged Promise

Just the other day, while programming in Scala, I was thinking how nice it is that Haskell hides non-strictness (a.k.a. laziness) underneath, so no obnoxious lazy stream creation/forcing needs to be done. And then it struck me: how cool would it be to treat Promises in a language the same way that Haskell treats lazy values? Would such a language even make sense? How would you program in such a language?

Let's explore! You can find all the code included in this post in a more useful form here.

Promise

Here's a very simple Promise implementation written in Scheme, with support for asynchronous resolving & error rejection, which we'll need in order to explore this weird proposition:

(define *promises* '())

(define (make-promise value state then handle thunk)
  (list '&promise value state then handle thunk))

;; Field accessors omitted.

(define (promise fun)
  (let* ((val '())
         (state 'pending)
         (on-resolve id)
         (on-reject id)
         (resolve (lambda (v)
                    (set! val v)
                    (set! state 'resolved)
                    (on-resolve val)))
         (reject (lambda (e)
                   (set! val e)
                   (set! state 'rejected)
                   (on-reject val)))
         (then (lambda (t)
                 (if (equal? state 'resolved)
                     (t val)
                     (set! on-resolve t))))
         (handle (lambda (h)
                   (if (equal? state 'rejected)
                       (h val)
                       (set! on-reject h))))
         (p (make-promise (lambda () val)
                          (lambda () state)
                          then
                          handle
                          (lambda () (fun resolve reject)))))
    (set! *promises* (cons p *promises*))
    p))

Continue reading