[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: specializer metaobjects
- To: Gregor Kiczales <gregor@parc.xerox.com>
- Subject: Re: specializer metaobjects
- From: kanderso@DINO.BBN.COM
- Date: Mon, 5 Nov 1990 08:25:24 PST
- Cc: mop.PARC@xerox.com
- In-reply-to: "Your message of Sun, 04 Nov 90 14:47:53 -0800. <90Nov4.144757pst.284@spade.parc.xerox.com>"
Fake-Sender: gregor@parc.xerox.com
X-NS-Transport-ID: 08002008D0FD0003D6A3
Date: Sun, 4 Nov 1990 14:47:53 PST
From: Gregor Kiczales <Gregor@parc.xerox.COM>
Subject: specializer metaobjects
To: mop.PARC@xerox.com
In the current metaobject protocol is that EQL specializers are not
objects (with their own special class). Aside from being conceptually
gross, this leads to a number of problems. There are several methods
that, in a silly way, are specialized to CONS. It also means that the
MOP doesn't point the way for users who want to add a new kind of
specializer. It doesn't make it clear that they should add a new kind
of object for the new specializers rather than, for example, further
overloading CONS.
...
Here is some naive model implementation code:
(defclass class (specializer) ..)
(defun intern-class-specializer (class-name)
(find-class class-name))
(defclass eql-specializer (specializer)
((object :initarg :object
:reader eql-specializer-object)))
(defvar *eql-specializers* (make-hash-table :test #'eql))
(defun intern-eql-specializer (object)
(or (gethash object *eql-specializers*)
(setf (gethash object *eql-specializers*)
(make-instance 'eql-specializer :object object))))
So, a defmethod form and expansion would be something like:
(defmethod foo ((x foo) (y (eql bar))) ..)
(...
(make-instance 'standard-method
:specializers (list (intern-class-specializer 'foo)
(intern-eql-specializer bar))
.
.)
...)
Defmethod should really by written in terms of a gf like:
(intern-specialize specializer)
(defmethod intern-specializer ((s symbol))
(find-class s))
right?
Note that the intern-xxx functions will have to be specified in order to
allow users to do anonymous creation of methods with EQL specializers.
If the user wants to do something like the slot class specializers
discussed at the CLOS workshop they would do:
(defclass slot-class-specializer (specializer)
((slot-name :initarg :slot-name ..)
(class :initarg :class ..)))
(defvar *slot-class-specializers* (make-hash-table :test #'equal))
(defun intern-slot-class-specializer (slot-name class-name)
(let ((class (find-class class-name)))
(or (gethash (cons slot-name class) *slot-class-specializers*)
(setf (gethash (cons slot-name class) *slot-class-specializers*)
(make-instance 'slot-class-specializer
:slot-name slot-name
:class class)))))
and a method definition and expansion would look like:
(define-method foo ((x foo)
(y (eql bar))
(z (slot a baz))) ;means that the value of the
;slot named A of this argument
;should have class BAZ
..)
(...
(make-instance 'my-method
:specializers (list (intern-class-specializer 'foo)
(intern-eql-specializer bar)
(intern-slot-class-specializer 'a 'baz))
.
.)
...)
I like this idea. Of course, a lot of the mop now specialized on
standard-class will have to specialized on specializer, which is
probably a good thing, except for the editing.
Question:
(defmethod foo (z (slot a bar)) ...) is a method specialized for
objects that have (eq (class-of (slot-value z 'a)) (find-class 'bar)).
(intern-specializer '(slot a bar)) returns an instance of class
'slot-specializer.
How to refer to this class to specialize methods on it?
(defmethod ((s (eql (intern-specializer '(slot a bar))))) ...) ?
or do we have a specializer for specializers:
(defmethod ((s (specializer '(slot a bar)))) ...)
k