Issue: SYMBOL-MACROS-AND-PROCLAIMED-SPECIALSReferences: SYMBOL-MACROLET, SPECIAL proclamation,
AUGMENT-ENVIRONMENT,
CONSTANTP, VARIABLE-INFORMATION
Related issues: Issue SYMBOL-MACROLET-DECLARE
Issue SYMBOL-MACROLET-SEMANTICS
Issue SYNTACTIC-ENVIRONMENT-ACCESS
Issue CONSTANTP-ENVIRONMENT
Issue CONSTANTP-DEFINITION
Category: CLARIFICATION
Edit history: v1, 15 Feb 1991, Sandra Loosemore
v2, 13 Mar 1991, Sandra Loosemore
Problem description:
Can a symbol-macro definition shadow a variable that has been
PROCLAIMed SPECIAL or defined as a constant using DEFCONSTANT?
Both SPECIAL proclamations and DEFCONSTANT definitions pervasively
affect the semantics of variable bindings. The question is whether a
symbol-macro binding of a symbol in the variable namespace is a
variable binding in this sense.
Note that issues SYMBOL-MACROLET-DECLARE and SYNTACTIC-ENVIRONMENT-ACCESS
require that an error be signalled if a SPECIAL declaration is supplied
for a name being bound as a symbol-macro.
There are two proposals, SHADOWING-PERMITTED and SIGNALS-AN-ERROR.
Proposal (SYMBOL-MACROS-AND-PROCLAIMED-SPECIALS:SHADOWING-PERMITTED):
Clarify that a SYMBOL-MACRO definition of a symbol shadows any other
interpretation of that symbol as a variable, even if the symbol is
a keyword or has been PROCLAIMed SPECIAL or defined as a constant
using DEFCONSTANT.
Note that lexical shadowing of keywords and defined constants
requires the use of an environment argument with CONSTANTP (see issue
CONSTANTP-ENVIRONMENT). Clarify that if the first argument to
CONSTANTP is a symbol that is a keyword or globally defined as a
constant, CONSTANTP must return true only if that symbol is not
lexically shadowed by a symbol-macro definition in the specified
environment. Likewise, VARIABLE-INFORMATION returns :SYMBOL-MACRO
rather than :CONSTANT as its first value if the symbol is a keyword
or defined constant that has been lexically shadowed by a symbol-macro
definition in the specified environment.
Rationale:
This is a reasonable interpretation to some people.
Proposal (SYMBOL-MACROS-AND-PROCLAIMED-SPECIALS:SIGNALS-AN-ERROR):
Clarify that a SYMBOL-MACRO definition of a symbol that is a keyword
or that has been PROCLAIMed SPECIAL or defined as a constant using
DEFCONSTANT is not permitted.
Require SYMBOL-MACROLET to signal an error if any of the symbols being
bound as a symbol-macro are keywords, PROCLAIMed SPECIAL or defined as
a constant using DEFCONSTANT.
Require AUGMENT-ENVIRONMENT to signal an error if any of the symbols in
the :SYMBOL-MACRO alist are keywords, PROCLAIMed SPECIAL or defined as a
constant using DEFCONSTANT.
Rationale:
This is a reasonable interpretation to some people.
There is also a compatibility problem if CONSTANTP is permitted to
be sensitive to the lexical environment in which the form appears
(see the cost to users section below).
Examples:
#1: (defvar *foo* nil)
(symbol-macrolet ((*foo* t))
*foo*)
Under proposal SHADOWING-PERMITTED, this returns T.
Under proposal SIGNALS-AN-ERROR, an error is signalled.
#2: (defconstant frob "frob-constant")
(defmacro see-if-constant (form)
`(progn ,form ,(constantp form)))
(symbol-macrolet ((frob (funcall #'some-hairy-function)))
(see-if-constant frob))
Under proposal SHADOWING-PERMITTED, this returns T; note that
the call to CONSTANTP returns a value appropriate for the
null lexical environment but does not take into account the
local symbol-macro definition of FROB.
Under proposal SIGNALS-AN-ERROR, an error is signalled.
Current Practice:
Apparently shadowing is permitted in some implementations but not
others.
Cost to Implementors:
Proposal SHADOWING-PERMITTED is more work than SIGNALS-AN-ERROR
since all calls to CONSTANTP within the implementation need to be
examined to see whether an environment argument must be passed. This
also requires that something other than EVAL (like FUNCALL of ENCLOSE)
be used to compute the value of something that is CONSTANTP.
Cost to Users:
Many applications that now use CONSTANTP assume that the value it returns
is not sensitive to the lexical environment in which the form appears.
(Since CONSTANTP has not previously been specified to accept an
environment argument, it is hard to see how any other interpretation
could be made.) Proposal SHADOWING-PERMITTED represents an incompatible
change in this respect. All calls to CONSTANTP within user programs
would have to be examined to see whether an environment argument must
be passed. This also requires that something other than EVAL (like
FUNCALL of ENCLOSE) be used to compute the value of something that is
Cost of non-adoption:
The language specification is unnecessarily vague.
Performance impact:
Probably none.
Benefits:
The cost of non-adoption is avoided.
Esthetics:
Seems to depend on who you talk to.
Most people seem to acknowledge that shadowing proclaimed specials and
defined constants with symbol-macros is abominable programming style.
Some people think disallowing shadowing complicates the language
unnecessarily by introducing yet another special case.
Some people think permitting shadowing complicates the language
unnecessarily by destroying the "globalness" of special proclamations
and constant definitions.
Discussion:
This issue was discussed on the x3j13 mailing list in May/June 1990.