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

dynamic binding



Sorry!  Accidentally fired off an incomplete message to T-Users.  Let me
try again.
			- Jonathan
--------------------

    Date: Fri, 29 Jul 83 19:22:50 PDT
    From: PATEL at UCLA-LOCUS.ARPA

    In writing some code I came across a need for dynamic binding. I
    tried "bind", but it doesn't seem to work the way I thought it
    would. Either there is a bug, or my understanding is faulty. I was
    trying to define some functions that would "throw" if there was an
    error, but I did not want to define them within the corresponding
    "catch". So, I thought of defining them outside the catch, and then
    dynamically binding the name of the escape procedure. However, as
    you can see from the transcript, it seems that it didn't quite work.
    Either "catch" did not bind "blech" correctly before evaluating the
    "bind" expression, or "bind" did not do its job quite well?

    This is VAX/Unix T version 2.6 (63)
    > (define (foo x) (if (> x 5) (blech 'big) 'small))
    #{Procedure FOO}
    > (catch bleep (bind ((blech bleep)) (foo 7)))
    BIG
    > (catch blech (bind ((blech blech)) (foo 7)))

    ** Error: variable BLECH has no value
    >> (exit)

BIND does a temporary assignment to a lexically bound variable; it is
implemented as a simple macro, and does not have any knowledge of "local"
or "global" variables.  In the above CATCH which produced the error, you
weren't binding the variable BLECH which was apparent to FOO, you
were binding the one which was apparent in the body of the CATCH.

    (bind ((blech bleep)) (foo 7))

is like

    (let ((save blech)) (set blech bleep) (block0 (foo 7) (set blech save)))

so that this looks like a normal LISP "special" binding; the global
value of blech is altered.  However, the same kind of expansion for the
other BIND gives:

    (catch blech (bind ((blech blech)) (foo 7)))

==>

    (catch blech (let ((save blech))
		   (set blech blech)
		   (block0 (foo 7)
			   (set blech save))))

So when FOO gets called, its BLECH is unbound, because a different BLECH
got assigned.

This is unlike what "dynamic binding" does in most Lisps, but is
semantically simpler, and more consistent with the idea that there is
only one kind of binding - no variables are really "global".

(The actual expansion of BIND is more complicated, to make sure that
bindings are undone when THROW's happen; and of course "save" is a
gensym.)