home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #27 / NN_1992_27.iso / spool / comp / lang / clos / 1008 < prev    next >
Encoding:
Internet Message Format  |  1992-11-23  |  25.2 KB

  1. Path: sparky!uunet!spool.mu.edu!sol.ctr.columbia.edu!ira.uka.de!chx400!sicsun!disuns2!disun47.epfl.ch!matomira
  2. From: matomira@disun47.epfl.ch (Fernando Mato Mira)
  3. Newsgroups: comp.lang.clos
  4. Subject: Re: Extending syntax/semantics of method specializers
  5. Message-ID: <1992Nov23.113551@disun47.epfl.ch>
  6. Date: 23 Nov 92 10:35:51 GMT
  7. References: <1992Nov20.221251.28590@jpl-devvax.jpl.nasa.gov> <9211210425.AA12235@verdi.iisd.sra.com>
  8. Sender: news@disuns2.epfl.ch
  9. Organization: Ecole Polytechnique Federale de Lausanne
  10. Lines: 797
  11. Nntp-Posting-Host: disun47.epfl.ch
  12.  
  13. Here is a transcript of the suggestions related to the subject that I sent to the X3 committee.
  14. Comments and corrections will be appreciated (especially on (3)). Tell me if you need more info.
  15.  
  16. Contents:
  17.   (1) DEFCLASS-GENERIC-CLASSES (Necessary to understand (2))
  18.   (2) DEFMETHOD-GENERIC-CLASSES (To the point)
  19.   (3) TYPE-SPECIFIER-BY-ASSOCIATION (To the point, but inmature)
  20.  
  21. Appendixes:
  22.   (4) TYPE-OF-FUNCTION
  23.   (5) TYPE-FOR-METHODS
  24.  
  25. ==============================================================================
  26. Forum:    Objects
  27. Issue:  DEFCLASS-GENERIC-CLASSES
  28.  
  29. References:   Draft 12.24: 7-61..65;50;1..11;30..34;88..89
  30.               CLtL2: 822..826;775,781 
  31.  
  32. Related issues: TYPE-SPECIFIER-BY-ASSOCIATION
  33.                 DEFMETHOD-GENERIC-CLASSES
  34.  
  35. Category: ADDITION
  36.  
  37. Edit history: Mato Mira -- 19 Nov 1992
  38.               
  39.  
  40. Problem description:
  41.  
  42. The current implemention of CLOS does not allow for the creation of generic
  43. classes, that is, classes where slot types are determined by type parameters.
  44. Under the current implementation, this inhibits the creation of type 
  45. specifiers in the style of "(list integer)" for user-defined classes.
  46.  
  47. Proposal (DEFCLASS-GENERIC-CLASSES:EXTEND): 
  48.  
  49. ALTERNATIVE-1 : (DEFCLASS-GENERIC-CLASSES:EXTEND-FOR-TYPE-GENERICITY)
  50.                 Type genericity only (other parameters,e.g. size, not allowed)
  51.  
  52. DEFCLASS class-name ({superclass-spec}*)                 [Macro]
  53.          ({slot-specifier}*) [[class-option]]
  54.  
  55. DEFCLASS class-name specialized-lambda-list ({superclass-spec}*)     [Macro]
  56.          ({slot-specifier}*) [[class-option]]
  57.  
  58. superclass-spec ::= restricted-class-spec
  59. restricted-class-spec ::= class-spec\built-in-class-spec     
  60. class-spec      ::= class-name | type-specifier
  61. specialized-lambda-list ::= ({var|specialized-parameter}*)
  62. specialized-parameter   ::= (var type-specifier)
  63.  
  64. Where the nonterminals not specified above are those found in CLtL2 822..826;839.
  65. The addition of an optional parameter in a non-standard position enables 
  66. backward compatibility of the extension with current programs. The semantics 
  67. do not change in that case.
  68.  
  69. The new form creates a list type specifier for the class, according to the 
  70. lambda list provided in the definition.
  71.  
  72. Class metaobjects should be created with an additional initialization argument:
  73. :direct-lambda-list. 
  74. A new generic function: class-direct-lambda-list should be implemented to 
  75. access this information in class metaobjects.
  76.  
  77. MAKE-INSTANCE class &rest initargs                         [Generic function]
  78. MAKE-INSTANCE (class standard-class) &rest initargs           [Primary method]
  79. MAKE-INSTANCE (class symbol) &rest initargs                   [Primary method]
  80.  
  81. The definition of MAKE-INSTANCE stays unchanged, except for the fact that the 
  82. first initarg can be a list of arguments which must be congruent with the 
  83. lambda list of the corresponding DEFCLASS, and where each element must be a 
  84. type specifier denoting a subtype of the corresponding parameter of the 
  85. previously mentioned lambda list.
  86. Instance allocation functions should be recoded to enforce the bindings.
  87. The bindings could be accesible in initialization functions in one of four ways:
  88.  
  89. 1. By defining a keyword and passing a list containing the bindings as an 
  90.   initarg.
  91.  
  92. 2. By adding a required parameter to the specification of INITIALIZE-INSTANCE, etc.
  93.  
  94. 3. By making the parameters bound in the dynamic environment.
  95.  
  96. 4. By adopting DEFMETHOD-GENERIC-CLASSES
  97.   
  98.  
  99.  
  100. ALTERNATIVE-2 : (DEFCLASS-GENERIC-CLASSES:EXTEND-FOR-ALL-GENERICITIES)
  101.                 All genericities allowed
  102.  
  103. DEFCLASS class-name ({superclass-spec}*)                 [Macro]
  104.          ({slot-specifier}*) [[class-option]]
  105.  
  106. DEFCLASS class-name specialized-lambda-list ({superclass-spec}*)     [Macro]
  107.          ({slot-specifier}*) [[class-option]]
  108.  
  109. superclass-spec         ::= restricted-class-spec
  110. restricted-class-spec   ::= class-spec\built-in-class-spec     
  111. class-spec              ::= class-name | type-specifier
  112. specialized-lambda-list ::= ({var|specialized-parameter}*)
  113. specialized-parameter   ::= (var type-specifier) | (var (type type-specifier))
  114.  
  115. When the parameter consists only of a variable, t is assumed as the 
  116. corresponding type.
  117. With this specification, a complete homogeneity with the built-in types
  118. is obtained. Even arrays, supporing type specifiers of the form 
  119. "(array integer 3)" can be programmed in this way.
  120. This capability can be used to enforce required initargs for instances.
  121.  
  122.  
  123. MAKE-INSTANCE class &rest initargs                         [Generic function]
  124. MAKE-INSTANCE (class standard-class) &rest initargs           [Primary method]
  125. MAKE-INSTANCE (class symbol) &rest initargs                   [Primary method]
  126.  
  127. Where the nonterminals not specified above are those found in CLtL2 848
  128. The definition of MAKE-INSTANCE stays unchanged, except for the fact that the 
  129. first initarg can be a list of arguments which must be congruent with the 
  130. lambda list of the corresponding DEFCLASS, and where each element must be an 
  131. instance of the type associated to the corresponding parameter of the 
  132. previously mentioned lambda list.
  133. Instance allocation functions should be recoded to enforce the bindings.
  134.  
  135. Examples:
  136.  
  137. ALTERNATIVE-1
  138.  
  139. (DEFCLASS tree ((info-type t)) () 
  140.       ((info :accessor info :initarg :info 
  141.          :type info-type))
  142.       (children :accessor children :initarg :children 
  143.             :type (or nil (tree info-type))))
  144.  
  145. (DEFCLASS matrix-tree ((elem-type number)) ((tree (array elem-type (* *)))))
  146.  
  147. (DEFCLASS float-matrix-tree ((matrix-tree float)) ()     ; NO LAMBDA LIST HERE
  148.           (:documentation "No problem with options thanks to atom"))  
  149.  
  150. (setf a-matrix (MAKE-INSTANCE 'matrix-tree (float) 
  151.            :info (make-array '(4 4) :element-type 'float
  152.            :initial-element 0.0)))
  153. (defun foo (a)
  154.   (declare (type (matrix-tree float) a))
  155.   (let (x)
  156.     (declare float x)
  157.     (setf x (aref (info a) 0 0))))    ; COULD BE COMPILED WITHOUT 2 TYPE CHECKS
  158.                                        IF TYPE-SPECIFIER-BY-ASSOCIATON PASSES
  159. ALTERNATIVE-2
  160.  
  161. (DEFCLASS tree ((info-type (type t))) () 
  162.       ((info :accessor info :initarg :info 
  163.          :type info-type))
  164.       (children :accessor children :initarg :children 
  165.             :type (or null (tree info-type))))
  166.  
  167. (DEFCLASS matrix-tree ((elem-type (type number)) 
  168.                (row-dim fixnum) (col-dim fixnum))
  169.   ((tree (array elem-type (row-dim  col-dim)))) ()
  170.   (:default-initargs :info (make-array `(,row-dim ,col-dim) 
  171.                        :element-type elem-type
  172.                        :initial-element 0.0)))
  173.  
  174.  
  175. #! If DEFMETHOD-GENERIC-CLASSES approved
  176.  
  177. (DEFCLASS matrix-tree ((elem-type (type number)) 
  178.                (row-dim fixnum) (col-dim fixnum))
  179.   ((tree (array elem-type (row-dim  col-dim)))) ())
  180.  
  181.  
  182. (DEFMETHOD initialize-instance :after 
  183.   ((instance (matrix-tree ?elem-type ?row-dim ?col-dim))         
  184.    &key ((:initial-element init-elem 0 init-elem-specified-p)))
  185.   (proclaim `(type ,?elem-type init-elem))  
  186.   (with-slots (info)
  187.       (if init-elem-specified-p
  188.     (setf info (make-array `(,?row-dim ,?col-dim) 
  189.                  :element-type ?elem-type
  190.                  :initial-element init-elem))
  191.     (setf info (make-array `(,?row-dim ,?col-dim) 
  192.                    :element-type ?elem-type)))))
  193. !#
  194.  
  195. (DEFCLASS float-matrix-tree ((row-dim fixnum) (col-dim fixnum))
  196.   ((matrix-tree float row-dim col-dim)) ())
  197.  
  198. (DEFCLASS homogeneous-transform-tree                      ; NO LAMBDA LIST HERE
  199.   ((float-matrix-tree 4 4)) ())
  200.    (:documentation "No problem with options thanks to atom"))  
  201.  
  202. (setf h-matrix (MAKE-INSTANCE 'matrix-tree (float 4 4))) 
  203.  
  204. (defun foo (a)
  205.   (declare (type (matrix-tree float) a))
  206.   (let (x)
  207.     (declare float x)
  208.     (setf x (aref (info a) 0 0))))    ; COULD BE COMPILED WITHOUT 2 TYPE CHECKS
  209.                                         IF TYPE-SPECIFIER-BY-ASSOCIATON PASSES
  210.  
  211.  
  212. Rationale:
  213.  
  214. Have a consistent type system capable of powerful declarations useful
  215. for optimization and verification purposes.
  216.  
  217. Current practice:
  218.  
  219. No Common Lisp implementation works this way.
  220. Generic classes are supported by other languages, such as Eiffel.
  221.  
  222. Cost to Implementors:
  223.  
  224. Minimal if declarations are ignored with respect to optimization.
  225.  
  226. Cost to Users:
  227.  
  228. None
  229.  
  230. Cost of non-adoption:
  231.  
  232. More burdensome and error-prone speed optimization and program verification 
  233. process.
  234.  
  235. Performance impact:
  236.  
  237. It would allow compiler optimizations for speed.
  238.  
  239. Benefits:
  240.  
  241. No need to use risky 'safety 0' declarations improve performance.
  242. Homogeneity of user defined classes and built-in classes type specifiers.
  243. "Conventional" language users might take LISP more seriously.
  244.  
  245. Esthetics:
  246.  
  247. Improved.
  248.  
  249. Discussion:
  250. ==============================================================================
  251. Forum:    Objects
  252. Issue:  DEFMETHOD-GENERIC-CLASSES
  253.  
  254. References: Draft 12.24: 7-18..25;66..72  
  255.             CLtL2: 826..842
  256.  
  257. Requires: DEFCLASS-GENERIC-CLASSES
  258.  
  259. Related issues: TYPE-SPECIFIER-BY-ASSOCIATION
  260.                 
  261. Category:     ADDITION
  262.  
  263. Edit history: Mato Mira -- 19 Nov 1992
  264.  
  265. Problem description:
  266.  
  267. [See DEFCLASS-GENERIC-CLASSES for an introduction]
  268. If DEFCLASS-GENERIC-CLASSES is approved, it would be possible to extend
  269. method dispatching to discriminate according to specializations of the
  270. type specifiers corresponding to generic classes.
  271. This would also be the most elegant way of accessing specialization 
  272. arguments in initialization functions.
  273.  
  274.  
  275.  
  276. Proposal (DEFMETHOD-GENERIC-CLASSES:EXTEND)                  [Macro]
  277.  
  278. DEFMETHOD function-name {method-qualifier}*
  279.           specialized-lambda-list
  280.           [[{declaration}* | doc-string]] {form}*
  281.  
  282. specialized-lambda-list ::= 
  283.       ({var | (var parameter-specializer)}*
  284.        [&optional {var | var [initform [supplied-p-parameter]])}* ]
  285.        [&rest var]
  286.        [&key {specialized-keyword-parameter}* [&allow-other-keys]]
  287.        [&aux {var | (var [initform])}*])
  288.  
  289. parameter-specializer ::= symbol | (eql eql-specializer-form) | type-spec
  290. type-spec ::= (symbol {specializer}*)
  291. specializer ::= ?var | (?var parameter-specializer) | parameter-specializer
  292.  
  293. Where the nonterminals not specified above are those found in CLtL2 826..842
  294. When using the form (?var parameter-specializer). IN THIS CASE, ALL THE OTHER 
  295. UNRESTRICTED REFERENCES TO ?var ARE EXPANDED TO THE RESTRICTED FORM (including
  296. those appearing in LIKE forms, if TYPE-SPECIFIER-BY-ASSOCIATION passes).
  297. It is an error to specify two or more different restrictions for the same
  298. variable.
  299.  
  300. Examples:
  301.  
  302. [see (DEFCLASS-GENERIC-CLASSES:EXTEND) for class definitions]
  303.  
  304. (DEFMETHOD initialize-instance :after 
  305.   ((instance (matrix-tree ?elem-type ?row-dim ?col-dim))         
  306.    &key ((:initial-element init-elem nil init-elem-specified-p)))
  307.   (proclaim `(type ,?elem-type init-elem))  
  308.   (with-slots (info)
  309.       (if init-elem-specified-p
  310.     (setf info (make-array `(,?row-dim ,?col-dim) 
  311.                  :element-type ?elem-type
  312.                  :initial-element init-elem))
  313.     (setf info (make-array `(,?row-dim ,?col-dim) 
  314.                    :element-type ?elem-type)))))
  315.  
  316. (DEFMETHOD initialize-instance :after 
  317.   ((instance (matrix-tree (?elem-type real) ?row-dim ?col-dim))         
  318.    &key ((:initial-element init-elem 0.0)))
  319.   (proclaim `(type ,?elem-type init-elem))  
  320.   (with-slots (info)
  321.     (setf info (make-array `(,?row-dim ,?col-dim) 
  322.                  :element-type ?elem-type
  323.                  :initial-element init-elem)))) 
  324.  
  325. (DEFMETHOD initialize-instance :after 
  326.   ((instance (matrix-tree float ?row-dim ?col-dim))         
  327.    &key ((:initial-element init-elem 0.0)))
  328.   (proclaim `(type ,?elem-type init-elem))  
  329.   (with-slots (info)
  330.     (setf info (make-array `(,?row-dim ,?col-dim) 
  331.                  :element-type 'float
  332.                  :initial-element init-elem))))
  333.  
  334.  
  335. Rationale:
  336.  
  337. If generic classes are accepted, this extension increases expressive power
  338. and elegance (except maybe for `?').
  339.  
  340. Current practice:
  341.  
  342. No lisp implementation works this way now.
  343.  
  344. Cost to Implementors:
  345.  
  346. Minor
  347.  
  348. Cost to Users:
  349.  
  350. None
  351.  
  352. Cost of non-adoption:
  353.  
  354. Loss of elegance.
  355.  
  356. Performance impact:
  357.  
  358. Dynamic method dispatching could be somewhat slower.
  359.  
  360. Benefits:
  361.  
  362. Expressive power augmented.
  363. No need to change any specifications to pass class specialization arguments 
  364. to initialization functions
  365.  
  366. Esthetics: 
  367.  
  368. Improved
  369.  
  370. Discussion:
  371. ===============================================================================
  372. /////////////////////////////////////////////////////////////////////////////
  373. THE FOLLOWING IS A FIRST APPROACH TO THE IDEA. IT IS BY NO MEANS A CLEANED UP
  374. SPECIFICATION
  375. /////////////////////////////////////////////////////////////////////////////
  376.  
  377. Forum:    Types & Declarations
  378. Issue:  TYPE-SPECIFIER-BY-ASSOCIATION
  379.  
  380. References:   Draft 12.24: Section 4
  381.               CLTL2:  49..68
  382.                
  383.  
  384. Requires: TYPE-OF-FUNCTION
  385.           TYPE-FOR-METHODS
  386.  
  387. Category:      ADDITION
  388.  
  389. Edit history:  Mato Mira -- 19 Nov 1992
  390.                
  391.  
  392. Problem description:
  393.  
  394. The current implemention of Common Lisp and CLOS  donot allow for the 
  395. declaration of types by association, that is, determined by the 
  396. type of other LISP objects. This is much more problematic for CLOS 
  397. methods.
  398.  
  399.  
  400. Proposal: (TYPE-SPECIFIER-BY-ASSOCIATION:EXTEND)     (Alpha Version)
  401.  
  402. The symbol 'like' can be used as the car of a type specifier list, as follows:
  403.  
  404. (TYPE (LIKE object) var1 var2 ...)
  405. Where object can be any LISP object.
  406.  
  407. (TYPE (LIKE (signature-accessor function) var1 var2 ...))
  408. (TYPE (LIKE (signature-accessor method-type-with-variables function))
  409.           var1 var2 ...)
  410.  
  411. signature-accessor ::= VALUE | VALUE n | VALUES | 
  412.                       PARAMETER n | OPTIONAL n | KEY keyword | AUX n
  413.  
  414. method-type-with-variables and  function are used in an TYPE-OF
  415. expression with :general option to find the corresponding signature
  416. (see TYPE-FOR-METHODS).
  417.  
  418. The value accessors have the obvious meanings, the PARAMETER accessor
  419. can be used not only for required parameters, but also to access the type
  420. of the default values provided for optional parameters. The OPTIONAL, KEY
  421. and AUX accessors also serve to access the type of the default value of
  422. the corresponding parameters (t if none).
  423.  
  424. Note that, if declarations are not ignored,
  425. (proclaim `(TYPE ,(TYPE-OF object) var1 var2 ...))
  426.  
  427. differs from
  428.  
  429. (proclaim `(TYPE (LIKE object) var1 var2 ...))
  430.  
  431. in that the constraint should be mantained if the type of <object> changes
  432. by calling UPDATE-INSTANCE-FOR-DIFFERENT-CLASS.      
  433. This is also true for function redefinitions when using FTYPE-OF in a 
  434. declaration.
  435.  
  436. For completeness, it would be nice to be able to express type by asociation
  437. in parameter specializers of methods.
  438.  
  439. Examples:
  440.  
  441. ;;; The following can only be expressed by means of generic classes:
  442. ;;; See (DEFCLASS-GENERIC-CLASSES:EXTEND)
  443.  
  444. (defclass tree ((info-type t)) () 
  445.   ((info :type info-type))
  446.   (children :type (or nil (tree info-type))))
  447.  
  448. (defmethod info ((self tree))
  449.   (slot-value self info))
  450.  
  451. ;; Assuming the generation of:
  452. ;; (declaim (type (method ((tree ?typ) (eql 'info)) ?typ) #'slot-value))
  453. ;; 
  454. ;; Then it is possible to write:
  455.  
  456. (declaim
  457.  (type 
  458.   (method ((tree ?x)) 
  459.       (LIKE (value (method ((tree ?x) (eql 'info)) *) #'slot-value)))
  460.   #'info))
  461.  
  462. ;;Note the need of implementing slot-value with multi-methods for this to 
  463. ;;work.
  464.  
  465. ;; An extension of the specification of DEFMETHOD to accept LIKE expressions
  466. ;; would enable a user to write:
  467.  
  468. (defmethod (setf info) 
  469.     ((self (tree (?z t)))
  470.      (val (like (value (method ((tree ?z)) *) #'info))))  ;; SEE NOTE[1]
  471.   (setf (slot-value self) val))
  472.  
  473. NOTE[1] : Remember that the second ?z is expanded to (?z t) by DEFMETHOD
  474.   (DEFMETHOD-GENERIC-CLASSES:EXTEND), and that FTYPE has expanded the second 
  475.   ?typ to (?typ t) (FTYPE-FOR-METHODS:EXTEND), so the CADDR of the value 
  476.   `returned' by the FTYPE-OF form AFTER SUBSTITUTION is the correct 
  477.   expression `(?z t)
  478.  
  479. ;; Many cases (like the one above) do not require that much expressive power,
  480. ;; so it would be nice to be able to write something like:
  481.  
  482. (defmethod (setf info) 
  483.     ((self (tree (?z t)))
  484.      (val (like (value (info tree)))))   
  485.   (setf (slot-value self 'info) val))    
  486.  
  487. ;; and for multiple-valued expressions:
  488. (defmethod (setf n-infos) 
  489.     ((self (multi-info-tree (?z t)))
  490.      (val1 val2 ... valn (like (values (n-infos tree)))))
  491.   ...)
  492.  
  493. Rationale:
  494.  
  495. Permit more precise declarations for users who need them. Improve 
  496. theoretical purity of CLOS.
  497.  
  498. Current practice:
  499.  
  500. None in Common Lisp.
  501. Supported in Eiffel (obvious generator of the idea). No dynamic constraints.
  502.  
  503. Cost to Implementors:
  504.  
  505. If not adopted in defmethod: Minor if declarations are ignored,  
  506.                              small if redefinitions are ignored.
  507.  
  508. If adopted in defmethod (the most important context, actually):
  509.   small to average (without redefinition support)
  510.  
  511. If type constraint maintenance supported:
  512.   Average and up
  513.  
  514. Cost to Users:
  515.  
  516. None
  517.  
  518. Cost of non-adoption:
  519.  
  520. Higher cost of program modifications for users who make use of declarations.
  521. Much worse in the case of CLOS programs.
  522.  
  523. Performance impact:
  524.  
  525. More specific declarations when using methods could improve it when using 
  526. adecquate compilers.
  527.  
  528. Benefits:
  529.  
  530. Makes possible the use of more declarations, improving performance and program
  531. verification with adecquate compilers.
  532. Doesn't clash with the LISP philosophy, while at the same time promoting 
  533. acceptance of LISP for "conventional" concerns.
  534. Improved object-oriented programming methodology.
  535.  
  536. Esthetics:
  537.  
  538. Definitely subject to discussion
  539.  
  540. Discussion:
  541.  
  542.   "In the beginning, there was dynamically scoped LISP.
  543.    Then somebody remembered lexical scoping and fixed it.
  544.    Then structured programming and Pascal came, and LISP got a lot of new 
  545.    toys, such as FLET.
  546.    Object-oriented programming arrived, but, of course LISP programmers had 
  547.    already used flavors for a long time, so they only made things neater when
  548.    they adopted CLOS.
  549.    A lot other more things happened, influenced by other languages (even some
  550.    with few parentheses!!)
  551.    Now some guy happened to be stuck programming for two years in the 
  552.    non-higher-order language Eiffel, and to his surprise, he learned a couple
  553.    of things about OO programming methodology. Back to LISP, happy to be able
  554.    to use all the meta-power of CLOS, he finds that there are declarations he
  555.    cannot make. And he needs every cycle of his computer when doing VR. He 
  556.    can use unsafe declarations, of course, but why doing it when there is a 
  557.    way to do it right?
  558.    ...
  559.    Like with Pascal, the LISP gurus hold their breadth, and adopted the idea.
  560.    Of course they made sure that their way was more powerful than the original
  561.    one..."
  562.  
  563.    Even if type declarations are optional in general, one cannot forget that 
  564.    when programming methods one is explicity making use of them. While 
  565.    maintaining the freedom of not being forced to declare anything, the 
  566.    typing issue has acquired now a different dimension.
  567.  
  568.    This is a major non-trivial issue. A lot of discussion is required. This 
  569.    is more an "idea generator" and a requirements list than a specification.
  570. ============================================================================
  571. Forum:    Types & Declarations
  572. Issue:  TYPE-OF-FUNCTION
  573.  
  574. References:    Draft 12.24: 4-37..38;         
  575.            CLtL2: 227..228
  576.  
  577. Related issues: TYPE-FOR-METHODS
  578.                 TYPE-SPECIFIER-BY-ASSOCIATION
  579.     
  580. Category:      ADDITION
  581.  
  582. Edit history:  Mato Mira -- 19 Nov 1992
  583.  
  584. Problem description:
  585.  
  586. Under the current specification of CL, there is no way to recover the 
  587. signature of a function declared by means of FTYPE. This makes it 
  588. impossible to implement types by association when the source of the 
  589. specification is the type of an argument or of the result returned by a
  590. function.
  591.  
  592. Proposal (TYPE-OF-FUNCTION:EXTEND)
  593.  
  594.   Make TYPE-OF return the complete signature of a function declared by means of
  595. TYPE. 
  596.  
  597.  
  598. TYPE-OF object                        [Function]
  599.  
  600. Examples:
  601.  
  602. USER(1): (declaim (type (function (number) float) sin cos))
  603. T
  604. USER(2): (TYPE-OF #'cos)
  605. (FUNCTION (number) float)
  606.  
  607. USER(2): (proclaim `(type ,(caddr (type-of #'cos)) some-var))
  608. T
  609.  
  610. Rationale:
  611.  
  612. Type declarations are invertible, ftype declarations are not. Necessary for
  613. meta-programming with types.
  614.  
  615. Current practice:
  616.  
  617. None that I know of.
  618.  
  619. Cost to Implementors:
  620.  
  621. Minimal
  622.  
  623. Cost to Users:
  624.  
  625. Code that depends on the result of calling type-of on a funcional object 
  626. should be changed. 
  627.  
  628. Cost of non-adoption:
  629.  
  630. Impossibility of defining some powerful styles of declarations.
  631.  
  632. Performance impact:
  633.  
  634. None
  635.  
  636. Benefits:
  637.  
  638. More consistent language. Higher-order capabilities increased.
  639.  
  640. Esthetics:
  641.  
  642.  
  643. Discussion:
  644.  
  645.   LISP is the language where "you can do anything" (and even efficiently). 
  646. The current lack of support for this functionality goes against the 
  647. philosophy of LISP.
  648. ==========================================================================
  649. Forum:    Types & Declarations
  650. Issue:  TYPE-FOR-METHODS
  651.  
  652. References:    Draft 12.24: 4/19..21;37..38          CLtL2: 227..228
  653.  
  654. Related issues: TYPE-SPECIFIER-BY-ASSOCIATION
  655.         TYPE-OF-FUNCTION
  656.  
  657. Category:      ADDITION
  658.  
  659. Edit history:  Mato Mira -- 19 Nov 1992
  660.  
  661. Problem description:
  662.  
  663. Under the current specification of CL, there is no way to declare and
  664. recover the type returned by a method. This makes it impossible to 
  665. implement types by association when the source of the specification is 
  666. the type of an argument or of the result returned by a method.
  667.  
  668. Proposal (TYPE-FOR-METHODS:EXTEND)
  669.  
  670. (TYPE method-type-spec method-name-1 method-name-2 ...)
  671.  
  672. method-type-spec  ::= (method-type ({type-spec}*) {type-spec}*)
  673. Type-spec ::= (EQL form) | type-spec-with-vars
  674. method-type ::= METHOD ...
  675.  
  676. where type-spec-with-variables are regular type specifiers or type 
  677. specifiers where variables of the form ?var can be used to express 
  678. interrelationships. They can also be restricted to be of a certain type 
  679. by using the form (?var type-spec). IN THIS CASE, ALL THE OTHER UNRESTRICTED
  680. REFERENCES TO ?var ARE EXPANDED TO THE RESTRICTED FORM.
  681. It is an error to specify two or more different restrictions for the same
  682. variable.
  683.  
  684. TYPE-OF object                                            [Function]        
  685. TYPE-OF method-type-with-variables function            [Function]    
  686. TYPE-OF method-type-with-variables function :general        [Function]    
  687. TYPE-OF method-type-with-variables function :strict        [Function]    
  688.     
  689. where method-type-with-variables is a method-type where the CDR of the 
  690. argument list or the  method-type-with-variables can also be replaced by 
  691. variables to match all the remaining components of that part of the 
  692. signature. The symbol '*' can be used as an anonymous variable.
  693.  
  694. The first form is explained in (TYPE-OF-FUNCTION:EXTEND) for the particular 
  695. case of functions.
  696. The second form returns a list of all the matching signatures declared 
  697. for the methods of the generic function, including subtype relationships.
  698. The third form returns the most general matching signature declared 
  699. for the methods of the generic function, taking into account subtype 
  700. relationships.
  701. The fourth form returns a list of all the matching signatures declared 
  702. for the methods of the generic function, without taking into account
  703. subtypes.
  704.  
  705. EXTENSION:
  706.  
  707.  
  708.  
  709. IMPORTANT NOTE: Should be consistent with (DEFMETHOD-GENERIC-CLASSES:EXTEND), if
  710.  both are accepted.
  711.  
  712. Examples:
  713.  
  714. USER(1): (declaim (TYPE (method (number) number) sin cos))
  715. T
  716. USER(2): (declaim (TYPE (method (complex) complex) sin cos))
  717. T
  718. USER(3): (declaim (TYPE (method (real) real) sin cos))
  719. T
  720. USER(4): (declaim (TYPE (method (float) float) sin cos))
  721. T
  722. USER(5): (TYPE-OF #'cos)
  723. (CLOS:STANDARD-GENERIC-FUNCTION (number) number)
  724.  
  725. USER(6): (TYPE-OF '(method (number) number) #'cos :strict)
  726. ((CLOS:STANDARD-METHOD (number) number))
  727.  
  728. USER(7): (TYPE-OF '(method (t) *) #'cos)
  729. ((CLOS:STANDARD-METHOD (number) number)
  730.  (CLOS:STANDARD-METHOD (complex) complex)
  731.  (CLOS:STANDARD-METHOD (real) real) 
  732.  (CLOS:STANDARD-METHOD (float) float))
  733.  
  734. USER(8): (TYPE-OF '(method (t) *) #'cos :strict)
  735. NIL
  736.  
  737. USER(9): (TYPE-OF '(method (t) *) #'cos :general)
  738. (CLOS:STANDARD-METHOD (number) number)
  739.  
  740.  
  741. USER(10): (TYPE-OF '(method . *) #'cos)
  742. ((CLOS:STANDARD-METHOD (number) number)
  743.  (CLOS:STANDARD-METHOD (complex) complex)
  744.  (CLOS:STANDARD-METHOD (real) real)
  745.  (CLOS:STANDARD-METHOD (float) float))
  746.  
  747. USER(11): (TYPE-OF '(method (*) real) #'cos)
  748. ((CLOS:STANDARD-METHOD (real) real) 
  749.  (CLOS:STANDARD-METHOD (float) float))
  750.  
  751. USER(12): (TYPE-OF '(method (* . *) real) #'cos)
  752. ((CLOS:STANDARD-METHOD (real) real) 
  753.  (CLOS:STANDARD-METHOD (float) float))
  754.  
  755. USER(13): (TYPE-OF '(method (*) real) #'cos :strict)
  756. ((CLOS:STANDARD-METHOD (real) real))
  757.  
  758. USER(14): (TYPE-OF '(method (float) . *) #'cos)
  759. ((CLOS:STANDARD-METHOD (float) float))
  760.  
  761. ;;; GENERIC CLASS EXAMPLE - See (DEFCLASS-GENERIC-CLASSES:EXTEND)
  762.  
  763. USER(15) : (declaim (TYPE (method ((tree (?typ t)) (eql 'info)) ?typ) #'slot-value))
  764. T
  765. USER(16) : (TYPE-OF (method ((tree (?x t)) (eql 'info)) *) #'slot-value :general)
  766. (CLOS:STANDARD-METHOD ((tree (?x t)) (eql 'info)) (?x t)) ;;NOTE THE SUBSTITUTION
  767.  
  768. Rationale:
  769.  
  770. Necessary for meta-programming with method signatures
  771.  
  772. Current practice:
  773.  
  774. None.
  775.  
  776. Cost to Implementors:
  777.  
  778. Minor.
  779.  
  780. Cost to Users:
  781.  
  782. None
  783.  
  784. Cost of non-adoption:
  785.  
  786. Impossibility of defining some powerful styles of declarations
  787.  
  788. Performance impact:
  789.  
  790. None
  791.  
  792. Benefits:
  793.  
  794. More consistent language. Higher-order capabilities increased.
  795.  
  796. Esthetics:
  797.  
  798.  
  799. Discussion:
  800.  
  801.  
  802. -- 
  803. Fernando D. Mato Mira
  804. Computer Graphics Lab
  805. Swiss Federal Institute of Technology
  806. matomira@di.epfl.ch
  807.  
  808. NeXTMail : matomira@lignext.epfl.ch
  809. FAX      : +41 (21) 693 - 5328
  810.