[pro] macros expanding to defclass + some mop code
Pascal Costanza
pc at p-cos.net
Wed Dec 29 20:37:44 UTC 2010
On 27 Dec 2010, at 04:37, Sam Steingold wrote:
> Hi,
> I want to write a macro which would expand to a defclass + some code
> which uses the resulting class object using mop.
> e.g. (untested),
> (defmacro deffoo (class slots)
> `(progn
> (defclass ,class () ,slots)
> (defun foo (x)
> (list
> ,@(mapcar (lambda (ds)
> `(,(car (slot-definition-readers ds)) x))
> (class-direct-slots (find-class class)))))))
>
> which should expand
> (deffoo bar ((a :reader bar-a) (b :reader bar-b)))
> to something like this:
> (progn
> (defclass bar () ((a :reader bar-a) (b :reader bar-b)))
> (defun foo (x) (list (bar-a x) (bar-b x))))
>
> Alas, CLASS is not defined at read time when
> (class-direct-slots (find-class class))
> and
> (slot-definition-readers ds)
> want to be evaluated.
>
> So, how do I do this?
Just to be complete, I insist that the 'right' way to do this is to do this at runtime. Here is a sketch of how to do this in such a way that you don't suffer that much from additional runtime overheads:
(defclass foo-dependent () ((function-symbol :initarg :function-symbol))
(defmethod update-dependent
((class standard-class) (dependent foo-dependent) &rest initargs)
(declare (ignore initargs))
(setf (symbol-function (slot-value dependent 'function-symbol))
(compile nil `(lambda (x)
(list
,@(loop for slot in (class-direct-slots class)
for name = (slot-definition-name slot)
collect `(slot-value x ',name)))))))
(defmacro deffoo (class slots)
`(progn
(defclass ,class () ,slots)
(defun foo (x))
(add-dependent (find-class ',class) (make-instance 'foo-dependent :function-symbol 'foo))
(reinitialize-instance (find-class ',class))
',class))
[Untested.]
Other variations are possible, like using a method on finalize-inheritance instead of update-dependent, if you can afford to have a separate metaclass for this. If you are sure that the class doesn't change at runtime, you can still generate the body of the foo function at loadtime / runtime, after the complete class exists.
Of course, this adds to some amount of load-time overhead, which may not be acceptable under certain circumstances.
Pascal
--
Pascal Costanza, mailto:pc at p-cos.net, http://p-cos.net
Vrije Universiteit Brussel
Software Languages Lab
Pleinlaan 2, B-1050 Brussel, Belgium
More information about the pro
mailing list