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

DYNAMIC-WIND from: draft minutes of June 1992 meeting



   Date: Fri, 9 Oct 92 14:57:51 -0700
   From: William Clinger <will@skinner.cs.uoregon.edu>

	      Draft Minutes of the RnRS Authors meeting
			   25 June 1992
			    Xerox PARC
	       recorded and edited by William Clinger

   ...
   Dynamic-wind:  The semantics of (dynamic-wind before during after)
   should leave unspecified what happens if a throw occurs out of
   before or after.  It is best to defer interrupts during before and
   after.  Following these clarifications, DYNAMIC-WIND was then
   approved unanimously.

Leaving "unspecified what happens if a throw occurs out of before or
after" does not disallow throwing out of before or after; But then,
what is the extent of the "during" in "It is best to defer interrupts
during before and after"?

I think that the behaviour of DYNAMIC-WIND when escaping from "before"
and "after" clauses should be specified.  There are benefits to having
this behaviour specified and I don't see that any benefits derive from
having it not specified.

One use of escaping from an "after" clause is to implement an
interactive top level which continues to operate even after an error
occurs.  Notice that using DYNAMIC-WIND to accomplish this does not
require that all or even any interrupts or errors have handlers.
However, there is nothing about this proposal which disallows having
such handlers.  Using DYNAMIC-WIND for interactive top levels
eliminates the need for read-eval-print hooks.

---------

I propose first that the order of execution of clauses and changes of
dynamic state of a DYNAMIC-WIND be the same for the execution of the
DYNAMIC-WIND and for the escape to its middle thunk.

I further propose that the dynamic state of
 (DYNAMIC-WIND thunk1 thunk2 thunk3)
change between the execution of thunk1 and thunk2 and between the
execution of thunk2 and thunk3.

I further propose that the suggestion of deferal of interrupts during
thunk1 and thunk3 be removed because the duration of thunk1 and thunk3
is not well defined.

----------

Both MITScheme and SLIB use the order of dynamic state changes
expressed above.  The only other possible place for dynamic state
changes is before the execution thunk1 and after the execution of
thunk3.  Although it is possible to write the interactive top level
with this order, it is much easier to do with the order I propose.  If
the changes happen before thunk1 and after thunk3 one has to set state
to avoid infinite loops in thunk3s and in fact infinite loops are much
easier to inadvertantly create.

Here is code which shows the order in which dynamic state changes.

======================================================================

;;;; "dwindtst.scm", routines for characterizing dynamic-wind.
;;; Copyright (C) 1992 Aubrey Jaffer.

(define (dwtest n)
  (define cont #f)
  (display "testing escape from thunk") (display n) (newline)
  (display "visiting:") (newline)
  (call-with-current-continuation
   (lambda (x) (set! cont x)))
  (if n
      (dynamic-wind
       (lambda ()
	 (display "thunk1") (newline)
	 (if (eqv? n 1) (let ((ntmp n))
			  (set! n #f)
			  (cont ntmp))))
       (lambda ()
	 (display "thunk2") (newline)
	 (if (eqv? n 2) (let ((ntmp n))
			  (set! n #f)
			  (cont ntmp))))
       (lambda ()
	 (display "thunk3") (newline)
	 (if (eqv? n 3) (let ((ntmp n))
			  (set! n #f)
			  (cont ntmp)))))))
(define (dwctest n)
  (define cont #f)
  (define ccont #f)
  (display "creating continuation thunk") (newline)
  (display "visiting:") (newline)
  (call-with-current-continuation
   (lambda (x) (set! cont x)))
  (if n (set! n (- n)))
  (if n
      (dynamic-wind
       (lambda ()
	 (display "thunk1") (newline)
	 (if (eqv? n 1) (let ((ntmp n))
			  (set! n #f)
			  (cont ntmp))))
       (lambda ()
	 (call-with-current-continuation
	  (lambda (x) (set! ccont x)))
	 (display "thunk2") (newline)
	 (if (eqv? n 2) (let ((ntmp n))
			  (set! n #f)
			  (cont ntmp))))
       (lambda ()
	 (display "thunk3") (newline)
	 (if (eqv? n 3) (let ((ntmp n))
			  (set! n #f)
			  (cont ntmp))))))
  (cond
   (n
    (set! n (- n))
    (display "testing escape from continuation thunk") (display n) (newline)
    (display "visiting:") (newline)
    (ccont #f))))

(dwtest 1) (dwtest 2) (dwtest 3)
(dwctest 1) (dwctest 2) (dwctest 3)

======================================================================

With this program systems conforming to my proposal print out:

testing escape from thunk1
visiting:
thunk1
testing escape from thunk2
visiting:
thunk1
thunk2
thunk3
testing escape from thunk3
visiting:
thunk1
thunk2
thunk3
creating continuation thunk
visiting:
thunk1
thunk2
thunk3
testing escape from continuation thunk1
visiting:
thunk1
creating continuation thunk
visiting:
thunk1
thunk2
thunk3
testing escape from continuation thunk2
visiting:
thunk1
thunk2
thunk3
creating continuation thunk
visiting:
thunk1
thunk2
thunk3
testing escape from continuation thunk3
visiting:
thunk1
thunk2
thunk3