[r6rs-discuss] [Formal] SRFI-39 should be made an R6RS library

From: Abdulaziz Ghuloum <aghuloum>
Date: Wed Feb 21 04:35:27 2007

On Feb 21, 2007, at 3:21 AM, Michael Sperber wrote:

> Can you explain in simple terms why `swap' is needed rather than the
> restore-the-old-value semantics in the alternative version I posted?

Swapping is needed, rather than restoring the old value, so that when
you get out of the dynamic context, and then back in, the value of the
parameter is restored to what it was when you got out, not to what it
was when you first got in. Maybe a simple example is a better
explanation.

Using this definition of parameterize:

(define-syntax parameterize
   (syntax-rules ()
     [(_ ((x v)) e1 e2 ...)
      (let ([p x] [y v])
        (let ([swap (lambda () (let ([t (p)]) (p y) (set! y t)))])
          (dynamic-wind swap (lambda () e1 e2 ...) swap)))]))

(define P (make-parameter #f))

(write (P)) ; writes #f

(parameterize ([P #t])
   ;;; we're inside, so the value is #t
   (write (P))) ; => writes #t

;;; we're out
(write (P)) ; writes #f


(parameterize ([P #t])
   ;;; we're in and the value is #t
   (P 17)
   ;;; we're still in, and the value is 17
   (write (P))) ; writes 17

;;; we're out, and the value is restored to #f (in both implementations)
(write (P)) ; writes #f

(define out-k #f)

(parameterize ([P #t])
   ;;; the value is #t here
   (P 17)
   ;;; the value is 17 here
   (call/cc (lambda (k) (set! out-k k)))
   ;;; the continuation was captured when P was 17
   (write (P))) ; writes 17

;;; we're out and the value is #f
(write (P)) ; writes #f

(out-k) ; writes 17 since P was 17 when the continuation was captured
         ; the swap on the way out remembers that and the swap on the
         ; way back in reinstates it.

(write (P)) ; writes #f


Now using your definition of parameterize:

(define-syntax parameterize
   (syntax-rules ()
     [(_ ((x v)) e1 e2 ...)
      (let ([p x] [new v])
        (let ([prev (p)])
          (dynamic-wind
            (lambda () (p new))
            (lambda () e1 e2 ...)
            (lambda () (p prev)))))]))

Everything will run the same except that the call to (out-k) will write
#t instead of 17 since that's what your code does on entry (and re-
entry)
to the dynamic context: set the parameter to the same "new" value.

Basically, in your model, you lose side effects when you exit the
dynamic
context, while in Kent's model, side effects to parameters are
remembered
and restored properly.

Aziz,,,
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.r6rs.org/pipermail/r6rs-discuss/attachments/20070221/fcef5224/attachment.htm
Received on Wed Feb 21 2007 - 04:34:54 UTC

This archive was generated by hypermail 2.3.0 : Wed Oct 23 2024 - 09:15:01 UTC