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


    Date: Fri, 27 May 83 20:34:50 EDT
    From: Jim Meehan <Meehan>
    To:   T-Bugs
    Re:   BIND and SET

    You can SET a variable that has been defined with LET or with LSET but
    not with BIND.  Why not?

I'm not quite sure what you mean by this.  The manual says that BIND is
defined in terms of SET, so theoretically it doesn't introduce any
definition (binding) at all (unless SET does; see below).  BIND is a

    How is it that SET is permitted at the "top level"? That is, I don't
    have to say (LSET FOO ...) when I start up T.

Right now, if you SET a variable for which there's no binding, a binding
is created in the innermost locale, as with LSET.  This is a feature
which will be phased out over time.  It was introduced originally
because (a) we hadn't committed ourselves to a particular model of
variable bindings and multiple "global" environments until late in the
game, and (b) we wanted to make T look like a familiar Lisp for as long
as it took to commit to a solution, and to make transition to T as
painless as possible for the hapless Lisp user (hah!).

It was the consensus of Scheme hackers from both Yale and MIT that SET
of an unbound variable should be an error.  It's unclean to have a
primitive which sometimes does binding (i.e. declaration) and sometimes
doesn't; therefore it was decided that the binding primitive should be
distinguished from the assignment primitive.  Thus LSET ("local SET")
for the first, SET for the second.

The motivation for flushing the current SET feature is that its
interaction with block structure is bad.  Consider the following:

(locale a
  (locale b
    x			; [1]
    (set x 'foo)	; [2]
  x			; [3]
  (set x 'bar)		; [4]

To what binding of x does the reference at [1] refer?  Consider the
cases where [2] is deleted and where [4] is deleted, and consider
changes in evaluation (or compilation) order.  Consider that the
expressions may appear inside lambda-expressions and evaluated at some
arbitrary future date.  Consider evaluators and compilers and
other code-walkers which traverse expressions in different ways.
You'll see that the current version of SET is a mess.

The mess is mitigated somewhat by requiring LSETs.  Given a few
restrictions on evaluation order, many nice properties hold, e.g. the
ability to wrap a (locale () ...) around any expression E and get
equivalent code, if E has no LSET's or DEFINE's not inside some inner
locale-expression.  This kind of predictability and compilability
(i.e. cleanliness) makes the small amount of pain involved worthwhile.

Don't worry, there will be plenty of warning before the SET-becomes-LSET
feature is removed; there will probably be warning messages in the fall,
and full-fledged errors generated only later.  However, when the change
happens, even variables assigned with BIND will need to be LSET at some
appropriate "top-level" place.