Dear all,
Consider the following:
(defclass my-class ()
((slot-1 :initarg :slot-1 :accessor slot-1)
(slot-2 :initarg :slot-2 :accessor slot-2)
; and so on
)))
What is rather preferable if the typing effort can be minimized to:
(defclass my-class ()
((new-slot slot-1)
(new-slot slot-2)
;;
That is, 'new-slot' as a macro.
Now, if I do the above, the compiler (SBCL) complains that "new-slot"
is defined multiple times as identifier. I am rather new to CLOS, so
not really sure what forms are implemented as functions or macros. I
seek the wisdom of this group to enlighten me and show me The Way!
thanks
-maneesh
·········@gmail.com writes:
> Dear all,
>
> Consider the following:
>
> (defclass my-class ()
> ((slot-1 :initarg :slot-1 :accessor slot-1)
> (slot-2 :initarg :slot-2 :accessor slot-2)
> ; and so on
> )))
>
> What is rather preferable if the typing effort can be minimized to:
>
> (defclass my-class ()
> ((new-slot slot-1)
> (new-slot slot-2)
> ;;
>
> That is, 'new-slot' as a macro.
>
> Now, if I do the above, the compiler (SBCL) complains that "new-slot"
> is defined multiple times as identifier. I am rather new to CLOS, so
> not really sure what forms are implemented as functions or macros. I
> seek the wisdom of this group to enlighten me and show me The Way!
The problem is that defclass is a macro, and that the arguments to
macros are data, not code (as long as the macro doesn't specifies that
it will execute that part). So you just cannot use macros there.
On the other hand, you can define your own defclass macro:
(defmacro my-defclass (name superclasses slots &rest options)
`(defclass ,name ,superclasses
,(mapcar (function gen-my-slot) slots)
,@options))
(defun new-slot (name)
`(,name :initarg ,(intern (string name) "KEYWORD")
:accessor ,name))
(defun gen-my-slot (slot)
(if (atom slot)
slot
(if (eq 'new-slot (car slot))
(apply (function new-slot) (rest slot))
slot)))
(macroexpand-1 '(my-defclass my-class ()
((new-slot slot-1)
(new-slot slot-2)
(slot-3 :initarg :slot3 :accessor my-class-slot-3)
slot-4)))
-->
(DEFCLASS MY-CLASS NIL
((SLOT-1 :INITARG :SLOT-1 :ACCESSOR SLOT-1)
(SLOT-2 :INITARG :SLOT-2 :ACCESSOR SLOT-2)
(SLOT-3 :INITARG :SLOT3 :ACCESSOR MY-CLASS-SLOT-3)
SLOT-4)) ;
T
--
__Pascal Bourguignon__ http://www.informatimago.com/
"Debugging? Klingons do not debug! Our software does not coddle the
weak."
On Jun 15, 12:01 am, ····@informatimago.com (Pascal J. Bourguignon)
wrote:
> On the other hand, you can define your own defclass macro:
>
> (defmacro my-defclass (name superclasses slots &rest options)
> `(defclass ,name ,superclasses
> ,(mapcar (function gen-my-slot) slots)
> ,@options))
Check out some of Kenny Tilton's code. Its chock full of macros that
expand into CLOS classes. (see defmodel, defmd). Install cells and
macroexpand some of the examples to see how it works.
http://common-lisp.net/cgi-bin/viewcvs.cgi/cells/?cvsroot=cells
Andy Chambers wrote:
> On Jun 15, 12:01 am, ····@informatimago.com (Pascal J. Bourguignon)
> wrote:
>
>> On the other hand, you can define your own defclass macro:
>>
>> (defmacro my-defclass (name superclasses slots &rest options)
>> `(defclass ,name ,superclasses
>> ,(mapcar (function gen-my-slot) slots)
>> ,@options))
>
> Check out some of Kenny Tilton's code. Its chock full of macros that
> expand into CLOS classes. (see defmodel, defmd). Install cells and
> macroexpand some of the examples to see how it works.
>
> http://common-lisp.net/cgi-bin/viewcvs.cgi/cells/?cvsroot=cells
>
Lawdy how I love defmd! Should have done that years ago. Note that folks
who like it and do not want to expand into defmodel should be able to
easily convert it to go straight to defclass.
kt