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

LABELS vs. local defines

I don't have much to add to Kent's message.  I find the violation of the

  ((LAMBDA () exp))  <=>  exp

identity particularly bothersome.  For example, BLOCK must now be
primitive, whereas in T it could in principle be defined as a macro,
as it was in the original Scheme.

If, as in MIT Scheme, you say that (DEFINE ...) forms are not
expressions, but are syntactically "part" of the enclosing
LAMBDA-expression, then you're a little better off.  That is, they're
sort of like DECLARE forms in Common Lisp.  Thus, writing

  (IF ... (DEFINE ...) ...)

is simply a syntax error (as is (EVAL '(DEFINE ...) ...)).  This is
actually sort of the right idea.  It's very weird that (DEFINE ...)
forms are evaluated expressions.  They aren't in most non-Lisp-like
programming languages; what's the effect of executing a SUBROUTINE
statement in FORTRAN?...

However, you still have various problems with macros:

- Do you permit a macro expansion to contain a DEFINE?  This would seem
  desirable, since otherwise you couldn't have things like DEFINE-OPERATION.
  If so, you have to macro-expand a LAMBDA's body before you can start
  looking for its internal definitions (or lack thereof).

- Do you allow BLOCK to act as a splicing operation?  I.e. does

    (LAMBDA (...) (BLOCK (DEFINE A ...) (DEFINE B ...)) ... A ... B ...)

  do the right thing?  If not, then you can't have macros like
  DEFINE-STRUCTURE-TYPE which expand into multiple DEFINE's.  If so, then
  not only do you have to macro-expand, you have to descend into BLOCK's.
  Why is BLOCK singled out in this way?  (I suppose a macro expansion could
  yield *two* values: an expression, and a list of definitions....)

- If expansions can contain DEFINE's, then clients of the macro need to
  know what subforms are insulated by contours and which aren't.

MIT Scheme (at least, the version of it which is given to the ordinary
user) doesn't have macros, so these problems aren't grave.  That may be
the right solution.  However, the "hacker's version," which does have
macros, goes through a rather complicated transformation on
LAMBDA-bodies in order to figure out just what variables are getting
defined (it macroexpands, then flattens BLOCKs, then effectively
introduces an inner LET to cause the variables to be bound, then they
get SET at the proper place in the body).  "Top-level" DEFINE's are
handled in a totally different manner.  Pretty random.