home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!ogicse!mintaka.lcs.mit.edu!zurich.ai.mit.edu!jaffer
- From: jaffer@zurich.ai.mit.edu (Aubrey Jaffer)
- Newsgroups: comp.lang.scheme
- Subject: dynamic-wind
- Message-ID: <JAFFER.92Sep10234847@camelot.ai.mit.edu>
- Date: 11 Sep 92 04:48:47 GMT
- Article-I.D.: camelot.JAFFER.92Sep10234847
- Sender: news@mintaka.lcs.mit.edu
- Organization: M.I.T. Artificial Intelligence Lab.
- Lines: 82
-
- I posted the following message 2 weeks ago and received only one
- response. Perhaps no one will use dynamic-wind. Perhaps everyone was
- on vacation. Specifically:
-
- If a continuation is called from within <thunk1> which escapes into
- <thunk2>, should <thunk3> and then <thunk1> be called before <thunk2>?
-
- If a continuation is called from within <thunk1> which escapes into
- <thunk2>, should just <thunk1> be called before <thunk2>?
-
- If a continuation is called from within <thunk3> which escapes into
- <thunk2>, should <thunk3> and then <thunk1> be called before <thunk2>?
-
- If a continuation is called from within <thunk3> which escapes into
- <thunk2>, should just <thunk1> be called before <thunk2>?
-
- If a continuation is called from within <thunk1> which escapes into
- <thunk3>, should any additional thunks be called?
-
- If a continuation is called from within <thunk3> which escapes into
- <thunk1>, should any additional thunks be called?
-
- Here is code which I beleive implements the proposed DYNAMIC-WIND
- procedre for any R4RS compliant Scheme. Is this correct? If so, I
- will add it to SLIB. Notice that it works for
- call-with-current-continuation in <thunk2>. I have tried to make it
- consistent for <thunk1> and <thunk3> as well but I am not clear as to
- what should happen in this case.
- ======================================================================
- ; "dynwind.scm", wind-unwind-protect for Scheme
- ; Copyright (c) 1992, Aubrey Jaffer
-
- ;This facility is a generalization of Common Lisp `unwind-protect',
- ;designed to take into account the fact that continuations produced by
- ;CALL-WITH-CURRENT-CONTINUATION may be reentered.
-
- ; (dynamic-wind <thunk1> <thunk2> <thunk3>) procedure
-
- ;The arguments <thunk1>, <thunk2>, and <thunk3> must all be procedures
- ;of no arguments (thunks).
-
- ;DYNAMIC-WIND calls <thunk1>, <thunk2>, and then <thunk3>. The value
- ;returned of <thunk2> is returned as the result of DYNAMIC-WIND.
- ;<thunk3> is also called just before <thunk2> calls any continuations
- ;created by CALL-WITH-CURRENT-CONTINUATION. If <thunk2> captures its
- ;continuation as an escape procedure, <thunk1> is invoked just before
- ;continuing that continuation.
-
- (define *winds* '())
-
- (define (dynamic-wind <thunk1> <thunk2> <thunk3>)
- (<thunk1>)
- (set! *winds* (cons (cons <thunk1> <thunk3>) *winds*))
- (let ((ans (<thunk2>)))
- (set! *winds* (cdr *winds*))
- (<thunk3>)
- ans))
-
- (define call-with-current-continuation
- (let ((oldcc call-with-current-continuation))
- (lambda (proc)
- (let ((winds *winds*))
- (oldcc
- (lambda (cont)
- (proc (lambda (c2)
- (dynamic:do-winds *winds* winds)
- (cont c2)))))))))
-
- (define (dynamic:do-winds from to)
- (set! *winds* from)
- (cond ((eq? from to))
- ((null? from)
- (dynamic:do-winds from (cdr to))
- ((caar to)))
- ((null? to)
- ((cdar from))
- (dynamic:do-winds (cdr from) to))
- (else
- ((cdar from))
- (dynamic:do-winds (cdr from) (cdr to))
- ((caar to))))
- (set! *winds* to))
-