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

Dynamic variables



This is the proposal for adding dynamic variables (aka fluid binding) to
Scheme, as approved by consensus at the first meeting of BASH.  See my
message of 05 Jul 89 for the details of the motivations behind the
proposal.

We propose adding four procedures and one derived expression type to
Scheme:

(MAKE-DYNAMIC obj)                                     [Procedure]

Create and return a new ``dynamic variable'' whose global value is obj.

(DYNAMIC-REF dvar)                                     [Procedure]

Return the value of the given dynamic variable in the current dynamic
environment.

(DYNAMIC-SET! dvar obj)                                [Procedure]

Change the value of the given dynamic variable to obj in the current
dynamic environment.  The returned value is unspecified.

(CALL-WITH-DYNAMIC-BINDING dvar obj thunk)             [Procedure]

Invoke and return the value of the given thunk in a new, nested dynamic
environment in which the given dynamic variable has been bound to a new
location whose initial contents are the value obj.  This dynamic
environment has precisely the same extent as the invocation of the thunk
and is thus captured by continuations created within that invocation and
re-established by those continuations when they are invoked.

(DYNAMIC-BIND ((var-expr val-expr) ...) . body)           [Syntax]

Evaluates the var-exprs and val-exprs in an unspecified order; the
var-exprs should yield dynamic variables.  Returns the result of evaluating
the body in a new, nested dynamic environment in which the given dynamic
variables have new bindings, initialized to the given values.  This dynamic
environment has precisely the same extent as the evaluation of the body and
is thus captured by continuations created within the body and
re-established by those continuations on invocation.

The DYNAMIC-BIND derived expression type has the following rewrite rule:

    (dynamic-bind ((<var-expr1> <val-expr1>)
                   (<var-expr2> <val-expr2>)
                   ...
                   (<var-exprN> <val-exprN>))
       . <body>)

    is equivalent to

    (let ((var1 <var-expr1>)
          (val1 <val-expr1>)
          (var2 <var-expr2>)
          (val2 <val-expr2>)
          ...
          (varN <var-exprN>)
          (valN <val-exprN>)
          (body-thunk (lambda () . <body>)))

       (call-with-dynamic-binding var1 val1
          (lambda ()
             (call-with-dynamic-binding var2 val2
                (lambda ()
                   ...
                      (call-with-dynamic-binding varN valN
                         body-thunk) ... )))))

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

Some notes on this proposal:

-- I think that the ``call-with-dynamic-binding'' procedure was actually
named ``call-with-dynamic'' in the proposal passed by BASH, but that
sounded funny to me.  I'm willing to change it back, though, if anyone
objects to my changing it.

-- Should there be a ``dynamic?'' predicate that is true only of dynamic
variables?  I'm inclined to think so.

-- Should it be specified that dynamic variables are a new data type,
disjoint from the others?  I'm again so inclined.

-- Given ``dynamic-wind'', a portable shallow-binding implementation of the
proposal can be written for all single-processor implementations of Scheme.
It was suggested at the BASH meeting that something like this be done and
placed in the library.  As stated in earlier messages, multiprocessor
implementations will have to implement it more primitively; Jinx has
pointed out, however, that two simple procedures for accessing the
process-specific dynamic environment suffice.

-- This proposal does not specify whether or not
``call-with-dynamic-binding'' tail-calls the given thunk.  I think this is
proper.  It is possible for deep-binding implementations to use tail-call,
but only at the expense of passing the dynamic environment on every
procedure call.  In shallow binding implementations, it is probably not
possible at all.

	Pavel