[pro] macros expanding to defclass + some mop code

Martin Simmons martin at lispworks.com
Mon Dec 27 16:22:38 UTC 2010


>>>>> On Mon, 27 Dec 2010 09:28:48 -0500, Sam Steingold said:
> 
> On Mon, Dec 27, 2010 at 2:02 AM, Pascal Costanza <pc at p-cos.net> wrote:
> > On 27 Dec 2010, at 04:37, Sam Steingold wrote:
> >> 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.
> 
> no, these classes will not change at run time (they are actually structs);
> and even if they will, I will be using deffoo for that.
> 
> > If you are really sure that the class doesn't change at runtime,
> 
> I am.
> 
> > you can alternatively wrap the defclass form into an (eval-when (:compile-toplevel :load-toplevel :execute) ...)
> 
> nope. my macro calls MOP functions at macroexpansion time, so this
> eval-when will not help me.

This might work (by delaying the MOP functions until the defclass has been
evaluated at compile-time).

(defmacro list-all-slot-values-of-class-name (class)
  `(list
    ,@(mapcar (lambda (ds)
                `(,(car (slot-definition-readers ds)) x))
              (class-direct-slots (find-class class)))))

(defmacro deffoo (class slots)
  `(progn
     (eval-when (:compile-toplevel :load-toplevel :execute)
       (defclass ,class () ,slots))
     (defun foo (x)
       (list-all-slot-values-of-class-name ,class))))


> I wonder if the deprecated #, will help me.

Using load-time-value would be better.

-- 
Martin Simmons
LispWorks Ltd
http://www.lispworks.com/




More information about the pro mailing list