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

Issue: DECLARE-TYPE-FREE (Version 4)

The comment about Lucid's warning messages made me wonder -- it *isn't* 
invoked by the sample code in the problem description.  Consequently, 
I've amended the statement of the problem in what is intended to be a 
very friendly way (I also laid more of the "blame" at the clear 
proscription in CLtL p158, rather than on the percentage of people who 
think it "invalid".)   And I added "setf" to the "setq" part of the 
proposal -- probably one should understand the unqualified phrase 
"variable references" to mean "variable updating references" as well 
as "variable accessing references".

Looking over the past mail, I saw a few more loose tidbits that needed
to be cleaned up; in particular the msg:
    Date: Tue, 20 Sep 88  19:04:46 CDT
    From: David N Gray <Gray@DSG.csc.ti.com>
suggested the need for a re-wording of the "Rationale" and "Benefits" 
section, and I extend this to the "Esthetics" section too.

Finally, I added a bit to the discussion section, mostly reflecting
the current state regarding "compilers" that use specialized-storage
for type-declared variables (i.e., Lucid's "Production" compiler).

By the bye, I'm not happy with the part that allows nested type specifiers
to be overly general.  I'd prefer that the inner ones be subtypes of the 
outter ones, so that the program:
    (locally (declare (type x fixnum))
       (locally (declare (type x (or bit package)))
         (setq x 1)))
would be "in error"; i.e., inner types should be more sensitive to the
outter constraints.  But this would not be a "friendly amendment" or 
minor cleanup; so I haven't done anything about it.

-- JonL --


Issue:         DECLARE-TYPE-FREE

References:    CLtL p.158


Edit history:  Version 1, 18-Sep-88, Moon
               Version 2, 22-Sep-88, Moon
                (small edits to reflect mail discussion)
               Version 3, 22-Sep-88, Masinter
               Version 4, 27-Sep-88, JonL 

Problem description:

  Section 9.2 of CLtL, p158, says that a declaration specifier like
  (TYPE type var1 var2 ...) "... affects only variable bindings".  
  Since declarations can occur in contexts other than establishing 
  "variable bindings", most people interpret this statement to mean 
  that type declarations not in such context are either (1) completely 
  to be ignored, or (2) invalid CL  syntax.  Thus both of the following 
  forms would be suspect in that the type declarations could not have 
  any effect:

    (if (and (typep x 'fixnum) (typep y 'fixnum))
	(locally (declare (fixnum x y))		    ;LOCALLY does not bind
	  ...algorithm using x and y...)	    ; any variables.
	...similar algorithm using x and y...)

    (let ((y 'foo))
      (setq y 10)
      (let ((x 5))				    ;'y' is not being bound in
        (declare (fixnum y))			    ; this particular context.
        (incf y)
         ...random algorithm...))

  Avoid the phrase "affects only variable bindings".  Clarify that a type
  declaration means that it is an error for the value of the variable not
  to be a member of the declared type, within the scope of the declaration.
  Clarify that the above programs are valid, and that this  kind of 
  declaration means the same thing as wrapping a THE form around every 
  reference to the variable, including modifying references by setq or setf.
  Clarify that if nested type declarations refer to the same variable, then 
  the value of the variable must be a member of the intersection of the 
  declared types.


  It enables optimizing compilers to make use of the otherwise ignored
  type information.  Many people have often asked  for it, and there is 
  no strong reason to forbid it.

Current practice:

  Lucid implements DECLARE-TYPE-FREE:ALLOW already; but under some 
  circumstances the compiler issues a warning message that such usage 
  is an extension to Common Lisp.

Cost to Implementors:

  None, it is valid to ignore type declarations.

Cost to Users:

  None, this is a compatible addition.

Cost of non-adoption:

  Common Lisp will be less self-consistent.


  Programmers will be able to use type declaration to express their
  intent, rather than having to manually insert THE wrappers around 
  every reference.


  It is a simpler interpretation for type declaration specifiers, with
  fewer special cases; hence reduces the number of exceptions in the


  Another cleanup issue, DECLARATION-SCOPE, addresses the scope of 
  declarations. This proposal carefully uses the phrase "within the 
  scope of the declaration" to avoid confounding the two issues. 

  This issue has been discussed at the Fort Collins X3J13 meeting in
  November 1987, and at length on the various electronic mailing lists.

  At least one current implementation is able to generate more efficient
  code when declarations are associated with a particular binding, since
  it then has the option to choose type-specific specialized storage for 
  the runtime value of the variable.  So, for example, 

      (let ((x v)) (declare (type float x)) (+ x x))

  is sometimes more efficient than

      (let ((x v)) (locally (declare (type float x)) (+ x x)))

  However, the local type declarations allowed by this proposal do
  provide some useful information, even if it is not the *most* useful.
  It is possible for a sufficiently "smart" compiler to infer the 
  equivalent of a "binding declaration" when it can ascertain that the 
  type of the binding value -- 'v' above -- is commensurate with the 
  type locally declared over the scope of usage of the variable.

  It may be useful for a compiler to issue a warning whenever it finds
  nested type declarations referring to the same variable and the
  intersection of the declared types is null.