[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Some comments on ch.2.
Issues surrounding Symbol-Macrolet
- Incompatible Language Change
Without symbol-macrolet in the language, it's a true statement that a
symbol used as an s-expression in Common Lisp represents either a
lexical variable or a dynamic one, but nothing else. (defconstant's
count as dynamic variables about which some additional information
happens to be available. But that's not the point...) With
symbol-macrolet, that statement no longer holds: a harmless-looking
symbol may be "macro-defined" to be an arbitrary operation, full of
evil side-effects, and potentially side-affectable by anything else.
This means that macros (or other code-walkers) which think they know
how programs work can get fooled, because now symbols standing as
s-expressions can represent arbitrary computations. This means that
any code-walker which attempts to schedule side-effects cleverly may
(probably will) be fooled, since what was previously a variable, only
affectable by SETQ, and with no side-effects of its own, may now be
vulnerable to arbitrary side effects, and may in fact cause side
effects of its own.
A common "clever" technique is to generate a LET form which binds the
apparent arguments of a macro to gensym'd variables, EXCEPT that
arguments which are variables already are not rebound, for efficiency
considerations. These kinds of optimizations can now fail
catastrophically if symbols no longer exclusively represent variables.
SETQ forms can also admit new side-effects, and/or can be affected by
side-effects in an opaque manner. These will be even more subtle to
locate.
There's a sort of counter-argument that says that you can always use
LET to clean up side-effect ordering. Then (1) with a SSC that
shouldn't cost you anything, and (2) nobody said that eliding the LET
for variables was, in fact, legal. (1) sort of assumes that either
you have a SSC, or you aren't very serious about efficiency, and so
clever macros aren't an issue. (2) says that Common Lisp is not a
very safe place in which to write programs -- you need a written
guarantee in order to make even the most fundamental assumptions.
- Symbol-Macrolet should at least be a special form.
Therefore, symbol-macrolet should be a special form, rather than a
macro, and should cause changes to the environment. Complex macros
which accept an &environment argument could then use the
symbol-macrolet environment information to determine whether a given
symbol represents a variable or some other (arbitrary) form.
Also, if one wishes to make generalized variables look like regular
variables, then debugger support for this fairy tale is presumably
desirable. That support will be easier to come by if symbol-macrolet
is considered a special form.
- Who needs it, anyway?
with-accessors and with-slots could just as easily use regular
macrolet to define normal local macros which happen to accept no
arguments. Then one would write:
(setf (x) (* (rho) (cos (theta))))
instead of (setq x (* rho (cos theta))). Is it really such a big
effort to type the extra parens that it's worth screwing around with
some fundamental language assumptions?
Also, readmacros should be a reasonable alternative for the with-slots
and with-accessors uses planned for symbol-macrolet.
- It shouldn't be part of CLOS
Symbol-macrolet represents a change to Common Lisp, not an extension
which is part of CLOS. While admittedly the CLOS spec. calls for
other changes to the underlying language, this one seems to have the
least to do with CLOS per se.