[pro] macros expanding to defclass + some mop code

Alessio Stalla alessiostalla at gmail.com
Mon Dec 27 14:43:54 UTC 2010


On Mon, Dec 27, 2010 at 3:28 PM, Sam Steingold <sds at gnu.org> wrote:
> 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.
> I wonder if the deprecated #, will help me.
>
>> You could of course also decide to parse the slot definition forms yourself.
> I am too lazy for that :-(

How about:

(defmacro deffoo (class slots)
  `(progn
     ,(let ((defclass-form `(defclass ,class () ,slots)))
        (eval defclass-form)
        defclass-form)
     (defun foo (x) ...)))

This will execute the defclass-form twice, if you compile and load the
code containing the macro in the same session. So with structs it
might not work if your implementation signals an error on struct
redefinition (which IIRC it can do).

hth,
Alessio




More information about the pro mailing list