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:p...@p-cos.net, http://p-cos.net Vrije Universiteit Brussel Software Languages Lab Pleinlaan 2, B-1050 Brussel, Belgium _______________________________________________ pro mailing list pro@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/pro