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

define -- a modest proposal



I may have misunderstood your message, but I'm afraid you are still
confusing (local static) INTERNAL DEFINE with (dynamic, horrible
semantically) INCREMENTAL DEFINE.  They have nothing in common (except
sharing the keyword).

INTERNAL DEFINE does NOT create a new scope.  The scope is created by
the surrounding LAMBDA, LET, or LETREC expression, and is therefore
bounded by parentheses.

(let ()
  (define foo ...)
  (define bar ...)
  <some expression>)

should be exactly equivalent to

(letrec ((foo ...)
         (bar ...))
  <some expression>)

As a matter of fact, I originally implemented LETREC in MIT-Scheme
(and it is still implemented in this way in MIT CScheme, I believe),
by transforming the second expression into the first.

Thus, the (INTERNAL) DEFINEs do not establish the context.  The
context is established by LET.

Your proposal of separating DEFINE into

(make-local-variable 'foo)
(set! foo value)

seems to violate this semantics.  It appears to be advocating for
INCREMENTAL DEFINE, which is NOWHERE on the report.  Indeed, MIT
Scheme has a primitive procedure which implements INCREMENTAL DEFINE,
on top of which MAKE-LOCAL-VARIABLE could be implemented trivially,
but we are certainly not advocating for a feature we don't feel
comfortable with ourselves.

INTERNAL DEFINE is purely declarative, it does not involve ANY side
effects.  INCREMENTAL DEFINE, on the other hand, is mostly imperative,
and involves side effecting environments.

As far as I know (please correct me on this), INTERNAL DEFINE has no
semantic problems, its only problem is purely syntactic: it makes the
evaluator (compiler, syntaxer, code walker, whatever) harder to write
since it has to collect all the definitions which occur in a scope
before processing the expressions.  Since the report only allows 
definitions as the very first thing in a block (it's the only place
where they make sense), collecting them is trivial.