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

Re: [spr7115] (declaim (ignore...))

This is a folowup on the question whether (DECLAIM (IGNORE IGNORE)) or
(DECLAIM (IGNORE UNUSED)) were legal forms in Common Lisp, and if so,
what effect they have.  The intention is to implement the Lisp Machine
functionality of automatically assuming a lexical variable with the
name IGNORE should be silently ignored.

I had previously expressed the opinion that the declaimation on the
COMMON-LISP package symbol IGNORE would not be legal under the
principle that portable code is restricted from making any global
declarations or definitions on symbols in the CL package.  Bob
concurred, but this left unresolved the real point whether the
declamation would be effectual on some other innocent variable in one
of the implementation's packages.

I've now studied the applicable sections of the dpANS, and conclude
that the declamation would not have the desired effect.  The
definition of PROCLAIM (and equivalently, DECLAIM) states definitively
that name in a declaration specifier in a proclamation refer to
dynamic variables.  It is impossible for a proclamation or declamation
to refer to a lexical variable.  By analogy, a (DECLAIM (SINGLE-FLOAT
X)) would affect references to the special variable, as in

   (defun foo (y) (declare (single-float y) (special x)) (* x y))

but has no effect whatever on the variable X in the following

   (defun bar (x) (* 2.0 x))

unless X were declared special either globally (e.g. with DEFVAR) or
else in a special declaration lexically surrounding the DEFUN.  The
lexical binding of X is a new variable that isn't affected by
surrounding type or ignore declarations.

So, the user might be tempted to declaim UNUSED to be special.
Unfortunately this won't work because the IGNORE and IGNORABLE
declaration specifiers actually have two actions.  In addition to
suppressing compile-time warnings about variables being used or not
used contrary to the programmer's apparent intentions, they also are
defined to do this (dpANS entry for IGNORE, IGNORABLE):

   It is desirable ... to issue a warning if, within the scope or its
   binding ... any VAR is declared special.

The intention of this clause is that whether a special binding
variable is or is not used cannot be determined by a compiler (because
it is not a lexical property of the code) and therefore the following

    (lambda (x)
      (declare (ignore x))
      (declare (special x))

is nonsensical, or at least evidence of confusion, perhaps arising
from macro expansions that are not cooperating correctly.  I think
that the only effect of a global proclamation

   (declaim (ignore unused))

would be to signal error if anyone anywhere declares or proclaims
UNUSED to special.

In conclusion, I'm pretty sure this is the meaning of the dpANS.  But
I'm much less sure whether this particular consequence was intended or
unintended.  The dpANS explicitly allows that IGNORE and IGNORABLE can
be used globally in declamations, but it's not clear anyone thought
very specifically about the effects the changes and clarifications to
scoping semantics would have on these particular declamation
specifiers.  I'll try to kick it around with some other XS3J13
members, or look through the text of the voted actions and see if
anything applies.  BTW, none of this history is binding on the spec --
rather, what the spec says is what it says.  But if the spec doesn't
reflect the committee's intentions for whatever reason, there is some
chance it could still be changed.