[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Declarative LETREC and DEFINE



I agree that something has to be done to make LETREC and DEFINE purely
functional.  However, I think there is a simpler solution than the one
presented by Duba and Felleisen.

It is sufficient to state that in the evaluation of

  (letrec ((var1 val1) (var2 val2)...) body)

the continuation of the values val1, val2... can only be called once.
Calling one of these continuations more than once would be an error.
Note that no restriction is put on the body's continuation.

Expressing this semantic as a source to source transformation is rather
easy.  Currently, the above letrec is equivalent to:

(let ((var1 #f) (var2 #f) ...)
  (set! var1 val1)
  (set! var2 val2)
  ...
  body)

In my proposed semantic we would have:

(let ((var1 #f) (var2 #f) ...)
  (set! var1 (returns-once (lambda () val1)))
  (set! var2 (returns-once (lambda () val2)))
  ...
  body)

where `returns-once' is defined as

(define (returns-once thunk)
  (let ((hasnt-returned-yet? #t))
    (let ((result (thunk)))
      (if hasnt-returned-yet?
        (begin
          (set! hasnt-returned-yet? #f)
          result)
        <undefined-result>))))

A similar restriction could be put on DEFINE special forms.

Marc Feeley