[pro] macros expanding to defclass + some mop code

Pascal Costanza pc at p-cos.net
Mon Dec 27 07:02:25 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?

Since a class may be redefined at runtime, you want to use the MOP at runtime anyway. So the code should rather expand into something like this:

(defun foo (x)
  (loop for slot in (class-direct-slots (find-class 'some-class))
        collect (slot-value-using-class (find-class 'some-class) x slot)))

There are ways to tweak this, but the principle should be clear.

If you are really sure that the class doesn't change at runtime, you can alternatively wrap the defclass form into an (eval-when (:compile-toplevel :load-toplevel :execute) ...)

You could of course also decide to parse the slot definition forms yourself.


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