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

Issue: DECLARATION-SCOPE (Version 2)



I'm not a little dismayed at the verbosity of this proposal.  Does the
following 3-sentence summary encompass most of the statement of problem:

  (1) Some declarations only affect how a particular instance of a binding
      is interpreted.  [these are called 'bound' in the terminology of
      the proposal].

  (2) Some don't.  [i.e, they affect something else other than some
      property of a particular instance of a binding.]

  (3) Except for SPECIAL,  no declaration in category (1) is permitted
      to have any other interpretation.

[Thus (3) prevents the following "natural" extension of declare IGNORE:
   (locally 
     ...
     (let ((x <computation>))
       (declare (ignore x))
       <body-without-x>)
     ...)
 <==> 
   (locally (declare (ignore x)) 
     ...
     (let ((x <computation>))
       <body-without-x>)
     ...)
]


The proposal, then, is presumably to clarify that

  (4) The scope of a `bound' declaration is exactly the scope of the
      associated [lexical] variable or function.  

[Since only SPECIAL is permitted to have both 'free' and 'bound' meanings,
then (4) really only applies to it,  for otherwise, the scope of a 'bound'
declaration is simply the one binding it is attached to.]

A primary consequence of this is that 
     (let ((x <computation>))
       (declare (special x))
       <body>)
is not equivalent to
     (locally (declare (special x))
       (let ((x <computation>))
	 <body>))
nor is it equivalent to 
     (locally (declare (special x))
       (let ((x <computation>))
	 (declare (special x))
	 <body>))
because the LOCALLY form would be permitted to affect the references in
<computation> and the scope of the variable 'x' does not include the
form <computation>.  

On the other hand, because the following SPECIAL declaration is not
linked to the binding(s) occuring in the surrounding LET, then
     (let ((x <computation>))
       (declare (special y))
       <body>)
is equivalent to
     (locally (declare (special y))
       (let ((x <computation>))
	 <body>))
in which case the declaration *does* affect the (free) references to
'y' found in <computation>.

Is this indeed the intended effect?  If so, is this the answer to the
questions about how to gag the compiler messages about "free" variables
appearing in &optional (etc) init forms of defuns?



Now, I think (3) above has some nasty consequences; in particular the
inability to give local type declarations over a lexical interval.
MacLisp wasn't scoped like this.  I vaguely remember discussion a long
time ago that the reason why Common Lisp variable declarations aren't
scoped like this is because of the inadvertent capturing of lexically-
apparent declarations by macroexpanded code.  [Indeed, some implementations
of DEFSUBST still have the bug that they have macro-expansion semantics
rather than function-call semantics.]  

It would be a shame if the declarational scheme had to be castrated simply 
because no one could figure out a better solution to the captured lexical 
environment problem.  I really don't see that having one construct --
ordinary macros -- that can lose referential transparency is so bad; we
certainly need a "safe" version thereof, like DEFSUBST should be; but
this hardly seems the time to grossly revise the semantics of macro
expansion, which  have other problems with lack of transparency.  [Someone
may point out that the phrase "Kohlbecker's Thesis" ought to be invoked
here.]

If the macro-induced lack of "referential transparency" isn't a factor
at all in CL's prohibition against allowing "pervasive" declarations to
affect bindings found in enclosed forms, then I apologies for the above
two-paragraph excursion.  But I still would like to see a more succinct
3-or-4-sentence summary of this proposal's problem description.


-- JonL --