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

Macros -> declarations



    Date: Fri, 17 May 1985  23:50 EDT
    From: "Scott E. Fahlman" <Fahlman@CMU-CS-C.ARPA>

    Now there's an idea: flush local SPECIAL declarations altogether,
    keeping only global SPECIAL proclamations.  I'll have to think about
    this awhile to see if I really believe that we can do without these
    declarations, but it is certainly a very attractive suggestion at first
    glance.  Can anyone think of a really important use for such
    declarations?

I can provide a few from recent experience with Macsyma. I'm not sure they'll
convince you 100%, but hopefully they'll at least make you stop and think.
It largely depends on whether you consider the goal is to produce a language
that's clean and shiny or one that cares about things like compatibility with
the past where possible, etc. I think these goals conflict pretty badly. With
my language designer's hat on, I'd reject almost all of these arguments out of
hand. But since CL was designed by people prone to wear their politician's hats
a lot of the time, I'm of the impression that things like "compatibility with
the past" and such are likely to carry more weight, so here goes...

* Sometimes a function will need to be compiled "out of place" (eg,
  before the relevant DEFVAR is loaded). In such cases, the problem
  may go away if you move the definition containing the spurious
  reference to another file (which is processed after the DEFVAR),
  but the SPECIAL declaration may linger.

* In any large system which is being converted incrementally from some other
  Lisp dialect (eg, old Maclisp or a relative, Interlisp, ...), it may be
  desirable to incrementally convert the semantics of variables used by
  functions. Using local SPECIAL declarations, you can gradually whittle away
  the region in which certain specials are used. If you force global SPECIAL
  declarations, you undermine the ability to make such transitions incrementally.

* Although Macsyma is being converted for Common Lisp, it may continue to run
  in other dialects of Lisp as well. As such, FLET and friends may not be
  available in those dialects and a number of situations may arise where 
  local SPECIAL declarations provide a way of achieving compatibility with
  those otherwise-not-cooperating dialects.

* There are numerous examples of special variables being used as
  communication between three or four definitions. We've been working on
  converting:

  (DECLARE (SPECIAL X))
  (DEFUN FOO () ... refers to special X ...)
  (DEFUN BAR () ... refers to special X ...)
  (DECLARE (UNSPECIAL X))

  into

  (DEFUN FOO () (DECLARE (SPECIAL X)) ... refers to special X ...)
  (DEFUN BAR () (DECLARE (SPECIAL X)) ... refers to special X ...)

  This a couple of advantages worth noting.

  * Common Lisp has no UNSPECIAL declaration (that I could find).
    If the special is a common name like X, we need to not have every
    reference to X compiled SPECIAL. It may be very expensive and
    dangerous (ie, in terms of potential for typos, timing errors, etc)
    to change all 180 source files for Macsyma to use names that could
    reasonably be left SPECIAL all the time. (At some point we may
    consider this, but...)

  * It makes it explicit when you look at a particular definition
    just how the communication is being done (since mostly these variables
    don't have *...* around them.

  * It is a -very- common problem that we will modify a definition
    and just put that definition in a patch file, only to find it compiles
    differently out of context because the appropriate SPECIAL declarations
    were not present. Having the SPECIAL declarations in the definition
    means they will move with the definition into the patch file. (This 
    problem would be "solved" by making SPECIAL declarations global and
    outlawing UNSPECIAL, but would mean I'd have to rename an awful lot of 
    variables, which I mentioned above is a bit scary...)

----Fahlman:
    I don't understand Moon's comment that local SPECIAL declarations have
    mostly been used to simulate what FLET does better.  Can you elaborate a
    bit? 

I assume he meant that variables which must be accessed in downward funargs
(eg, to MAPCAR and user-defined friends) no longer have to be passed special.
Likewise, what people used to write as:

(DEFUN IN (OBJ TREE) (DECLARE (SPECIAL OBJ)) (IN1 TREE))

(DEFUN IN1 ()
  (DECLARE (SPECIAL OBJ))
  (COND ((ATOM TREE) (EQ OBJ TREE))
	(T (OR (IN1 (CAR TREE)) (IN1 (CDR TREE))))))

can now be written:

(DEFUN IN (OBJ TREE)
  (LABELS ((IN1 (TREE)
	     (COND ((ATOM TREE) (EQ OBJ TREE))
		   (T (OR (IN1 (CAR TREE)) (IN1 (CDR TREE)))))))
    (IN1 TREE)))

----Fahlman:
    As Moon points out, even with this change we would still need PARSE-BODY
    for macro writers,

or my &BODY hack. No sense in not providing both, though.

    but it would sure make life easier for the interpreter, since the other
    declarations can all be ignored unless you're doing tense error-checking.