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


would you say this supercedes:

References:   Declaring Global Variables and Named Constants (pp68-69),
	      Declaration Specifiers (p157)
Category:     ADDITION
Edit history: 07-Mar-88, Version 1 by Pitman
	      21-May-88, Version 2 by Pitman (correct test case, add discussion)
Status:	      For Internal Discussion

Problem Description:

  CLtL does not define a way to test to see if a variable has been
  proclaimed special (for the purposes of either binding or reference).

  Programs such as macros, code-walkers, and program-generating programs
  may need such information from time to time in order to do certain kinds
  of reasoning about code-motion, unused variables, etc.


  Add a function SPECIAL-VARIABLE-P by analogy with SPECIAL-FORM-P
  which is defined as:

  SPECIAL-VARIABLE-P symbol &optional environment	[Function]

  Returns T iff -symbol- names a variable which is SPECIAL in the
  indicated lexical -environment-. Otherwise, it returns NIL.
  It is an error if -symbol- is not a symbol. If not supplied, the
  -environment- defaults to NIL, meaning the null lexical environment.

  This function will be useful in determining whether a reference to
  the variable named by SYMBOL in the indicated ENVIRONMENT will be
  a special reference.

  Note: Since special variable proclamations are pervasive and
  declarations are not, the technique for determining whether binding
  the variable named by SYMBOL is not dependent on the surrounding
  lexical environment. It is instead dependent only on the global
  environment and on the declarations of the form which would accomplish
  the binding. Whether the variable has been globally proclaimed special
  can be determined by doing (SPECIAL-VARIABLE-P 'symbol). Whether the
  variable is locally declared SPECIAL can be checked only by parsing
  the declarations looking for (DECLARE ... (SPECIAL ... symbol ...)).

Test Case:

    (LIST* (TEST SPECIAL-FOO)				        ;0
	   (TEST FOO)
	   (LET ((SPECIAL-FOO 1) (FOO 1))
	     (LIST* (TEST SPECIAL-FOO)				;1
		    (TEST FOO)
		    (LET ((SPECIAL-FOO 2) (FOO 2))
		      (LIST* (TEST SPECIAL-FOO)			;2
			     (TEST FOO)
			     (LET ((SPECIAL-FOO 3) (FOO 3))
			       (LIST (TEST SPECIAL-FOO)		;3
				     (TEST FOO)))))))))
  => ((SPECIAL-FOO T) (FOO NIL)			;0
      (SPECIAL-FOO T) (FOO NIL)			;1
      (SPECIAL-FOO T) (FOO T)			;2
      (SPECIAL-FOO T) (FOO NIL))		;3


  This would allow programs that reason about other programs to obtain
  important information about SPECIAL declarations and proclamations.

Current Practice:

  Interpreters and compilers must, of necessity, have a way to do this

  In some implementations, information about special variable proclamations
  is kept on a symbol's plist, and users eventually "figure out" how to take
  advantage of that.

  In most implementations, getting information about special declarations
  is neither documented nor easy to "figure out".

  Symbolics Genera has undocumented internal function which does this.

Cost to Implementors:

  By necessity, compilers and interpreters must have a way to get the
  information returned by this facility. In general, it should just be
  a matter of providing a program interface to that facility.

Cost to Users:

  None. This is an upward-compatible extension.

Cost of Non-Adoption:

  Some code-walkers, macros, etc. would continue be hard to write in a
  portable way.


  The cost of non-adoption would be avoided.


  Although SPECIAL variables provide some benefit to Common Lisp, that 
  benefit has not been without price. It's difficult to do proper code
  analysis if lexical and special variables look the same. The presence
  of this operator makes it easier to write code which reasons clearly
  and correctly about other programs, and so will probably tend to
  improve the aesthetics of such programs.


  This proposal came to the Cleanup committee from the Japanese community.
  Pitman wrote it up formally.