From: matomira@disun47.epfl.ch (Fernando Mato Mira)
Newsgroups: comp.lang.clos
Subject: Re: Extending syntax/semantics of method specializers
Date: 23 Nov 92 10:35:51 GMT
Organization: Ecole Polytechnique Federale de Lausanne

Here is a transcript of the suggestions related to the subject that I sent to the X3 committee.
Comments and corrections will be appreciated (especially on (3)). Tell me if you need more info.

Contents:
  (1) DEFCLASS-GENERIC-CLASSES (Necessary to understand (2))
  (2) DEFMETHOD-GENERIC-CLASSES (To the point)
  (3) TYPE-SPECIFIER-BY-ASSOCIATION (To the point, but inmature)

Appendixes:
  (4) TYPE-OF-FUNCTION
  (5) TYPE-FOR-METHODS

==============================================================================
Forum:	Objects
Issue:  DEFCLASS-GENERIC-CLASSES

              CLtL2: 822..826;775,781 

Related issues: TYPE-SPECIFIER-BY-ASSOCIATION
                DEFMETHOD-GENERIC-CLASSES

Category: ADDITION

Edit history: Mato Mira -- 19 Nov 1992
              

Problem description:

The current implemention of CLOS does not allow for the creation of generic
classes, that is, classes where slot types are determined by type parameters.
Under the current implementation, this inhibits the creation of type 
specifiers in the style of "(list integer)" for user-defined classes.

Proposal (DEFCLASS-GENERIC-CLASSES:EXTEND): 

ALTERNATIVE-1 : (DEFCLASS-GENERIC-CLASSES:EXTEND-FOR-TYPE-GENERICITY)
                Type genericity only (other parameters,e.g. size, not allowed)

DEFCLASS class-name ({superclass-spec}*) 				[Macro]
         ({slot-specifier}*) [[class-option]]

DEFCLASS class-name specialized-lambda-list ({superclass-spec}*) 	[Macro]
         ({slot-specifier}*) [[class-option]]

superclass-spec ::= restricted-class-spec
restricted-class-spec ::= class-spec\built-in-class-spec     
class-spec      ::= class-name | type-specifier
specialized-lambda-list ::= ({var|specialized-parameter}*)
specialized-parameter   ::= (var type-specifier)

Where the nonterminals not specified above are those found in CLtL2 822..826;839.
The addition of an optional parameter in a non-standard position enables 
backward compatibility of the extension with current programs. The semantics 
do not change in that case.

The new form creates a list type specifier for the class, according to the 
lambda list provided in the definition.

Class metaobjects should be created with an additional initialization argument:
:direct-lambda-list. 
A new generic function: class-direct-lambda-list should be implemented to 
access this information in class metaobjects.

MAKE-INSTANCE class &rest initargs	   	     	     [Generic function]
MAKE-INSTANCE (class standard-class) &rest initargs	       [Primary method]
MAKE-INSTANCE (class symbol) &rest initargs	               [Primary method]

The definition of MAKE-INSTANCE stays unchanged, except for the fact that the 
first initarg can be a list of arguments which must be congruent with the 
lambda list of the corresponding DEFCLASS, and where each element must be a 
type specifier denoting a subtype of the corresponding parameter of the 
previously mentioned lambda list.
Instance allocation functions should be recoded to enforce the bindings.
The bindings could be accesible in initialization functions in one of four ways:
 
1. By defining a keyword and passing a list containing the bindings as an 
  initarg.

2. By adding a required parameter to the specification of INITIALIZE-INSTANCE, etc.

3. By making the parameters bound in the dynamic environment.

4. By adopting DEFMETHOD-GENERIC-CLASSES
  


ALTERNATIVE-2 : (DEFCLASS-GENERIC-CLASSES:EXTEND-FOR-ALL-GENERICITIES)
                All genericities allowed

DEFCLASS class-name ({superclass-spec}*) 				[Macro]
         ({slot-specifier}*) [[class-option]]

DEFCLASS class-name specialized-lambda-list ({superclass-spec}*) 	[Macro]
         ({slot-specifier}*) [[class-option]]

superclass-spec         ::= restricted-class-spec
restricted-class-spec   ::= class-spec\built-in-class-spec     
class-spec              ::= class-name | type-specifier
specialized-lambda-list ::= ({var|specialized-parameter}*)
specialized-parameter   ::= (var type-specifier) | (var (type type-specifier))

When the parameter consists only of a variable, t is assumed as the 
corresponding type.
With this specification, a complete homogeneity with the built-in types
is obtained. Even arrays, supporing type specifiers of the form 
"(array integer 3)" can be programmed in this way.
This capability can be used to enforce required initargs for instances.


MAKE-INSTANCE class &rest initargs	   	     	     [Generic function]
MAKE-INSTANCE (class standard-class) &rest initargs	       [Primary method]
MAKE-INSTANCE (class symbol) &rest initargs	               [Primary method]

Where the nonterminals not specified above are those found in CLtL2 848
The definition of MAKE-INSTANCE stays unchanged, except for the fact that the 
first initarg can be a list of arguments which must be congruent with the 
lambda list of the corresponding DEFCLASS, and where each element must be an 
instance of the type associated to the corresponding parameter of the 
previously mentioned lambda list.
Instance allocation functions should be recoded to enforce the bindings.

Examples:

ALTERNATIVE-1

(DEFCLASS tree ((info-type t)) () 
	  ((info :accessor info :initarg :info 
		 :type info-type))
	  (children :accessor children :initarg :children 
		    :type (or nil (tree info-type))))

(DEFCLASS matrix-tree ((elem-type number)) ((tree (array elem-type (* *)))))

(DEFCLASS float-matrix-tree ((matrix-tree float)) ()     ; NO LAMBDA LIST HERE
          (:documentation "No problem with options thanks to atom"))  

(setf a-matrix (MAKE-INSTANCE 'matrix-tree (float) 
	       :info (make-array '(4 4) :element-type 'float
	       :initial-element 0.0)))
(defun foo (a)
  (declare (type (matrix-tree float) a))
  (let (x)
    (declare float x)
    (setf x (aref (info a) 0 0))))	; COULD BE COMPILED WITHOUT 2 TYPE CHECKS
                                       IF TYPE-SPECIFIER-BY-ASSOCIATON PASSES
ALTERNATIVE-2

(DEFCLASS tree ((info-type (type t))) () 
	  ((info :accessor info :initarg :info 
		 :type info-type))
	  (children :accessor children :initarg :children 
		    :type (or null (tree info-type))))

(DEFCLASS matrix-tree ((elem-type (type number)) 
		       (row-dim fixnum) (col-dim fixnum))
  ((tree (array elem-type (row-dim  col-dim)))) ()
  (:default-initargs :info (make-array `(,row-dim ,col-dim) 
				       :element-type elem-type
				       :initial-element 0.0)))


#! If DEFMETHOD-GENERIC-CLASSES approved

(DEFCLASS matrix-tree ((elem-type (type number)) 
		       (row-dim fixnum) (col-dim fixnum))
  ((tree (array elem-type (row-dim  col-dim)))) ())


(DEFMETHOD initialize-instance :after 
  ((instance (matrix-tree ?elem-type ?row-dim ?col-dim))         
   &key ((:initial-element init-elem 0 init-elem-specified-p)))
  (proclaim `(type ,?elem-type init-elem))  
  (with-slots (info)
      (if init-elem-specified-p
	(setf info (make-array `(,?row-dim ,?col-dim) 
				 :element-type ?elem-type
				 :initial-element init-elem))
	(setf info (make-array `(,?row-dim ,?col-dim) 
			       :element-type ?elem-type)))))
!#

(DEFCLASS float-matrix-tree ((row-dim fixnum) (col-dim fixnum))
  ((matrix-tree float row-dim col-dim)) ())

(DEFCLASS homogeneous-transform-tree	                  ; NO LAMBDA LIST HERE
  ((float-matrix-tree 4 4)) ())
   (:documentation "No problem with options thanks to atom"))  

(setf h-matrix (MAKE-INSTANCE 'matrix-tree (float 4 4))) 

(defun foo (a)
  (declare (type (matrix-tree float) a))
  (let (x)
    (declare float x)
    (setf x (aref (info a) 0 0))))    ; COULD BE COMPILED WITHOUT 2 TYPE CHECKS
                                        IF TYPE-SPECIFIER-BY-ASSOCIATON PASSES


Rationale:

Have a consistent type system capable of powerful declarations useful
for optimization and verification purposes.

Current practice:

No Common Lisp implementation works this way.
Generic classes are supported by other languages, such as Eiffel.

Cost to Implementors:

Minimal if declarations are ignored with respect to optimization.

Cost to Users:

None

Cost of non-adoption:

More burdensome and error-prone speed optimization and program verification 
process.

Performance impact:

It would allow compiler optimizations for speed.

Benefits:

No need to use risky 'safety 0' declarations improve performance.
Homogeneity of user defined classes and built-in classes type specifiers.
"Conventional" language users might take LISP more seriously.

Esthetics:

Improved.

Discussion:
==============================================================================
Forum:	Objects
Issue:  DEFMETHOD-GENERIC-CLASSES

            CLtL2: 826..842

Requires: DEFCLASS-GENERIC-CLASSES

Related issues: TYPE-SPECIFIER-BY-ASSOCIATION
                
Category:     ADDITION

Edit history: Mato Mira -- 19 Nov 1992

Problem description:

[See DEFCLASS-GENERIC-CLASSES for an introduction]
If DEFCLASS-GENERIC-CLASSES is approved, it would be possible to extend
method dispatching to discriminate according to specializations of the
type specifiers corresponding to generic classes.
This would also be the most elegant way of accessing specialization 
arguments in initialization functions.



Proposal (DEFMETHOD-GENERIC-CLASSES:EXTEND)                  [Macro]

DEFMETHOD function-name {method-qualifier}*
          specialized-lambda-list
          [[{declaration}* | doc-string]] {form}*

specialized-lambda-list ::= 
      ({var | (var parameter-specializer)}*
       [&optional {var | var [initform [supplied-p-parameter]])}* ]
       [&rest var]
       [&key {specialized-keyword-parameter}* [&allow-other-keys]]
       [&aux {var | (var [initform])}*])

parameter-specializer ::= symbol | (eql eql-specializer-form) | type-spec
type-spec ::= (symbol {specializer}*)
specializer ::= ?var | (?var parameter-specializer) | parameter-specializer

Where the nonterminals not specified above are those found in CLtL2 826..842
When using the form (?var parameter-specializer). IN THIS CASE, ALL THE OTHER 
UNRESTRICTED REFERENCES TO ?var ARE EXPANDED TO THE RESTRICTED FORM (including
those appearing in LIKE forms, if TYPE-SPECIFIER-BY-ASSOCIATION passes).
It is an error to specify two or more different restrictions for the same
variable.

Examples:

[see (DEFCLASS-GENERIC-CLASSES:EXTEND) for class definitions]

(DEFMETHOD initialize-instance :after 
  ((instance (matrix-tree ?elem-type ?row-dim ?col-dim))         
   &key ((:initial-element init-elem nil init-elem-specified-p)))
  (proclaim `(type ,?elem-type init-elem))  
  (with-slots (info)
      (if init-elem-specified-p
	(setf info (make-array `(,?row-dim ,?col-dim) 
				 :element-type ?elem-type
				 :initial-element init-elem))
	(setf info (make-array `(,?row-dim ,?col-dim) 
			       :element-type ?elem-type)))))

(DEFMETHOD initialize-instance :after 
  ((instance (matrix-tree (?elem-type real) ?row-dim ?col-dim))         
   &key ((:initial-element init-elem 0.0)))
  (proclaim `(type ,?elem-type init-elem))  
  (with-slots (info)
	(setf info (make-array `(,?row-dim ,?col-dim) 
				 :element-type ?elem-type
				 :initial-element init-elem)))) 

(DEFMETHOD initialize-instance :after 
  ((instance (matrix-tree float ?row-dim ?col-dim))         
   &key ((:initial-element init-elem 0.0)))
  (proclaim `(type ,?elem-type init-elem))  
  (with-slots (info)
	(setf info (make-array `(,?row-dim ,?col-dim) 
				 :element-type 'float
				 :initial-element init-elem))))


Rationale:

If generic classes are accepted, this extension increases expressive power
and elegance (except maybe for `?').

Current practice:

No lisp implementation works this way now.

Cost to Implementors:

Minor

Cost to Users:

None

Cost of non-adoption:

Loss of elegance.

Performance impact:

Dynamic method dispatching could be somewhat slower.

Benefits:

Expressive power augmented.
No need to change any specifications to pass class specialization arguments 
to initialization functions

Esthetics: 

Improved

Discussion:
===============================================================================
/////////////////////////////////////////////////////////////////////////////
THE FOLLOWING IS A FIRST APPROACH TO THE IDEA. IT IS BY NO MEANS A CLEANED UP
SPECIFICATION
/////////////////////////////////////////////////////////////////////////////

Forum:	Types & Declarations
Issue:  TYPE-SPECIFIER-BY-ASSOCIATION

              CLTL2:  49..68
               

Requires: TYPE-OF-FUNCTION
          TYPE-FOR-METHODS

Category:      ADDITION

Edit history:  Mato Mira -- 19 Nov 1992
               

Problem description:

The current implemention of Common Lisp and CLOS  donot allow for the 
declaration of types by association, that is, determined by the 
type of other LISP objects. This is much more problematic for CLOS 
methods.


Proposal: (TYPE-SPECIFIER-BY-ASSOCIATION:EXTEND)     (Alpha Version)

The symbol 'like' can be used as the car of a type specifier list, as follows:

(TYPE (LIKE object) var1 var2 ...)
Where object can be any LISP object.

(TYPE (LIKE (signature-accessor function) var1 var2 ...))
(TYPE (LIKE (signature-accessor method-type-with-variables function))
		  var1 var2 ...)

signature-accessor ::= VALUE | VALUE n | VALUES | 
                      PARAMETER n | OPTIONAL n | KEY keyword | AUX n

method-type-with-variables and  function are used in an TYPE-OF
expression with :general option to find the corresponding signature
(see TYPE-FOR-METHODS).

The value accessors have the obvious meanings, the PARAMETER accessor
can be used not only for required parameters, but also to access the type
of the default values provided for optional parameters. The OPTIONAL, KEY
and AUX accessors also serve to access the type of the default value of
the corresponding parameters (t if none).

Note that, if declarations are not ignored,
(proclaim `(TYPE ,(TYPE-OF object) var1 var2 ...))

differs from

(proclaim `(TYPE (LIKE object) var1 var2 ...))

in that the constraint should be mantained if the type of <object> changes
by calling UPDATE-INSTANCE-FOR-DIFFERENT-CLASS.	  
This is also true for function redefinitions when using FTYPE-OF in a 
declaration.

For completeness, it would be nice to be able to express type by asociation
in parameter specializers of methods.

Examples:

;;; The following can only be expressed by means of generic classes:
;;; See (DEFCLASS-GENERIC-CLASSES:EXTEND)

(defclass tree ((info-type t)) () 
  ((info :type info-type))
  (children :type (or nil (tree info-type))))

(defmethod info ((self tree))
  (slot-value self info))

;; Assuming the generation of:
;; (declaim (type (method ((tree ?typ) (eql 'info)) ?typ) #'slot-value))
;; 
;; Then it is possible to write:

(declaim
 (type 
  (method ((tree ?x)) 
	  (LIKE (value (method ((tree ?x) (eql 'info)) *) #'slot-value)))
  #'info))

;;Note the need of implementing slot-value with multi-methods for this to 
;;work.

;; An extension of the specification of DEFMETHOD to accept LIKE expressions
;; would enable a user to write:

(defmethod (setf info) 
    ((self (tree (?z t)))
     (val (like (value (method ((tree ?z)) *) #'info))))  ;; SEE NOTE[1]
  (setf (slot-value self) val))

NOTE[1] : Remember that the second ?z is expanded to (?z t) by DEFMETHOD
  (DEFMETHOD-GENERIC-CLASSES:EXTEND), and that FTYPE has expanded the second 
  ?typ to (?typ t) (FTYPE-FOR-METHODS:EXTEND), so the CADDR of the value 
  `returned' by the FTYPE-OF form AFTER SUBSTITUTION is the correct 
  expression `(?z t)

;; Many cases (like the one above) do not require that much expressive power,
;; so it would be nice to be able to write something like:

(defmethod (setf info) 
    ((self (tree (?z t)))
     (val (like (value (info tree)))))   
  (setf (slot-value self 'info) val))    

;; and for multiple-valued expressions:
(defmethod (setf n-infos) 
    ((self (multi-info-tree (?z t)))
     (val1 val2 ... valn (like (values (n-infos tree)))))
  ...)

Rationale:

Permit more precise declarations for users who need them. Improve 
theoretical purity of CLOS.

Current practice:

None in Common Lisp.
Supported in Eiffel (obvious generator of the idea). No dynamic constraints.

Cost to Implementors:

If not adopted in defmethod: Minor if declarations are ignored,  
                             small if redefinitions are ignored.

If adopted in defmethod (the most important context, actually):
  small to average (without redefinition support)

If type constraint maintenance supported:
  Average and up

Cost to Users:

None

Cost of non-adoption:

Higher cost of program modifications for users who make use of declarations.
Much worse in the case of CLOS programs.

Performance impact:

More specific declarations when using methods could improve it when using 
adecquate compilers.

Benefits:

Makes possible the use of more declarations, improving performance and program
verification with adecquate compilers.
Doesn't clash with the LISP philosophy, while at the same time promoting 
acceptance of LISP for "conventional" concerns.
Improved object-oriented programming methodology.

Esthetics:

Definitely subject to discussion

Discussion:

  "In the beginning, there was dynamically scoped LISP.
   Then somebody remembered lexical scoping and fixed it.
   Then structured programming and Pascal came, and LISP got a lot of new 
   toys, such as FLET.
   Object-oriented programming arrived, but, of course LISP programmers had 
   already used flavors for a long time, so they only made things neater when
   they adopted CLOS.
   A lot other more things happened, influenced by other languages (even some
   with few parentheses!!)
   Now some guy happened to be stuck programming for two years in the 
   non-higher-order language Eiffel, and to his surprise, he learned a couple
   of things about OO programming methodology. Back to LISP, happy to be able
   to use all the meta-power of CLOS, he finds that there are declarations he
   cannot make. And he needs every cycle of his computer when doing VR. He 
   can use unsafe declarations, of course, but why doing it when there is a 
   way to do it right?
   ...
   Like with Pascal, the LISP gurus hold their breadth, and adopted the idea.
   Of course they made sure that their way was more powerful than the original
   one..."

   Even if type declarations are optional in general, one cannot forget that 
   when programming methods one is explicity making use of them. While 
   maintaining the freedom of not being forced to declare anything, the 
   typing issue has acquired now a different dimension.

   This is a major non-trivial issue. A lot of discussion is required. This 
   is more an "idea generator" and a requirements list than a specification.
============================================================================
Forum:	Types & Declarations
Issue:  TYPE-OF-FUNCTION

	       CLtL2: 227..228

Related issues: TYPE-FOR-METHODS
                TYPE-SPECIFIER-BY-ASSOCIATION
	
Category:      ADDITION

Edit history:  Mato Mira -- 19 Nov 1992

Problem description:

Under the current specification of CL, there is no way to recover the 
signature of a function declared by means of FTYPE. This makes it 
impossible to implement types by association when the source of the 
specification is the type of an argument or of the result returned by a
function.
 
Proposal (TYPE-OF-FUNCTION:EXTEND)

  Make TYPE-OF return the complete signature of a function declared by means of
TYPE. 


TYPE-OF object						[Function]

Examples:

USER(1): (declaim (type (function (number) float) sin cos))
T
USER(2): (TYPE-OF #'cos)
(FUNCTION (number) float)

USER(2): (proclaim `(type ,(caddr (type-of #'cos)) some-var))
T

Rationale:

Type declarations are invertible, ftype declarations are not. Necessary for
meta-programming with types.

Current practice:

None that I know of.

Cost to Implementors:

Minimal

Cost to Users:

Code that depends on the result of calling type-of on a funcional object 
should be changed. 

Cost of non-adoption:

Impossibility of defining some powerful styles of declarations.

Performance impact:

None

Benefits:

More consistent language. Higher-order capabilities increased.

Esthetics:


Discussion:

  LISP is the language where "you can do anything" (and even efficiently). 
The current lack of support for this functionality goes against the 
philosophy of LISP.
==========================================================================
Forum:	Types & Declarations
Issue:  TYPE-FOR-METHODS


Related issues: TYPE-SPECIFIER-BY-ASSOCIATION
		TYPE-OF-FUNCTION

Category:      ADDITION

Edit history:  Mato Mira -- 19 Nov 1992

Problem description:

Under the current specification of CL, there is no way to declare and
recover the type returned by a method. This makes it impossible to 
implement types by association when the source of the specification is 
the type of an argument or of the result returned by a method.
 
Proposal (TYPE-FOR-METHODS:EXTEND)

(TYPE method-type-spec method-name-1 method-name-2 ...)

method-type-spec  ::= (method-type ({type-spec}*) {type-spec}*)
Type-spec ::= (EQL form) | type-spec-with-vars
method-type ::= METHOD ...

where type-spec-with-variables are regular type specifiers or type 
specifiers where variables of the form ?var can be used to express 
interrelationships. They can also be restricted to be of a certain type 
by using the form (?var type-spec). IN THIS CASE, ALL THE OTHER UNRESTRICTED
REFERENCES TO ?var ARE EXPANDED TO THE RESTRICTED FORM.
It is an error to specify two or more different restrictions for the same
variable.

TYPE-OF object		                                    [Function]		
TYPE-OF method-type-with-variables function		    [Function]	
TYPE-OF method-type-with-variables function :general	    [Function]	
TYPE-OF method-type-with-variables function :strict	    [Function]	
	
where method-type-with-variables is a method-type where the CDR of the 
argument list or the  method-type-with-variables can also be replaced by 
variables to match all the remaining components of that part of the 
signature. The symbol '*' can be used as an anonymous variable.

The first form is explained in (TYPE-OF-FUNCTION:EXTEND) for the particular 
case of functions.
The second form returns a list of all the matching signatures declared 
for the methods of the generic function, including subtype relationships.
The third form returns the most general matching signature declared 
for the methods of the generic function, taking into account subtype 
relationships.
The fourth form returns a list of all the matching signatures declared 
for the methods of the generic function, without taking into account
subtypes.

EXTENSION:



IMPORTANT NOTE: Should be consistent with (DEFMETHOD-GENERIC-CLASSES:EXTEND), if
 both are accepted.

Examples:

USER(1): (declaim (TYPE (method (number) number) sin cos))
T
USER(2): (declaim (TYPE (method (complex) complex) sin cos))
T
USER(3): (declaim (TYPE (method (real) real) sin cos))
T
USER(4): (declaim (TYPE (method (float) float) sin cos))
T
USER(5): (TYPE-OF #'cos)
(CLOS:STANDARD-GENERIC-FUNCTION (number) number)

USER(6): (TYPE-OF '(method (number) number) #'cos :strict)
((CLOS:STANDARD-METHOD (number) number))

USER(7): (TYPE-OF '(method (t) *) #'cos)
((CLOS:STANDARD-METHOD (number) number)
 (CLOS:STANDARD-METHOD (complex) complex)
 (CLOS:STANDARD-METHOD (real) real) 
 (CLOS:STANDARD-METHOD (float) float))

USER(8): (TYPE-OF '(method (t) *) #'cos :strict)
NIL

USER(9): (TYPE-OF '(method (t) *) #'cos :general)
(CLOS:STANDARD-METHOD (number) number)


USER(10): (TYPE-OF '(method . *) #'cos)
((CLOS:STANDARD-METHOD (number) number)
 (CLOS:STANDARD-METHOD (complex) complex)
 (CLOS:STANDARD-METHOD (real) real)
 (CLOS:STANDARD-METHOD (float) float))

USER(11): (TYPE-OF '(method (*) real) #'cos)
((CLOS:STANDARD-METHOD (real) real) 
 (CLOS:STANDARD-METHOD (float) float))

USER(12): (TYPE-OF '(method (* . *) real) #'cos)
((CLOS:STANDARD-METHOD (real) real) 
 (CLOS:STANDARD-METHOD (float) float))

USER(13): (TYPE-OF '(method (*) real) #'cos :strict)
((CLOS:STANDARD-METHOD (real) real))

USER(14): (TYPE-OF '(method (float) . *) #'cos)
((CLOS:STANDARD-METHOD (float) float))

;;; GENERIC CLASS EXAMPLE - See (DEFCLASS-GENERIC-CLASSES:EXTEND)

USER(15) : (declaim (TYPE (method ((tree (?typ t)) (eql 'info)) ?typ) #'slot-value))
T
USER(16) : (TYPE-OF (method ((tree (?x t)) (eql 'info)) *) #'slot-value :general)
(CLOS:STANDARD-METHOD ((tree (?x t)) (eql 'info)) (?x t)) ;;NOTE THE SUBSTITUTION

Rationale:

Necessary for meta-programming with method signatures

Current practice:

None.

Cost to Implementors:

Minor.

Cost to Users:

None

Cost of non-adoption:

Impossibility of defining some powerful styles of declarations

Performance impact:

None

Benefits:

More consistent language. Higher-order capabilities increased.

Esthetics:


Discussion:


-- 
Fernando D. Mato Mira
Computer Graphics Lab
Swiss Federal Institute of Technology
matomira@di.epfl.ch

NeXTMail : matomira@lignext.epfl.ch
FAX 	 : +41 (21) 693 - 5328
Newsgroups: comp.lang.clos