Reputation: 319
I have defined the following simple macro:
(defmacro define-class (class-name)
`(defclass ,class-name ()()))
And now I want to use it in the following function:
(defun create-data (mode)
(define-class mode))
After compiling the last function I get the following message, the variable MODE is defined but never used.
And when I execute the function to create a class "myclass", I get instead the creation of a class of type "mode":
(create-data 'myclass)
#<STANDARD-CLASS MODE>
Seems that my argument is not used? How can I get the function create-data to use the argument?
Upvotes: 1
Views: 151
Reputation: 139411
I would use something like this:
CL-USER 86 > (defmacro define-class (class-name)
`(defclass ,class-name ()()))
DEFINE-CLASS
CL-USER 87 > (defun create-data (mode)
(funcall (compile nil `(lambda ()
(define-class ,mode)))))
CREATE-DATA
CL-USER 88 > (create-data 'bar)
#<STANDARD-CLASS BAR 402016CC73>
Above uses code generation and the built-in compiler.
Upvotes: 2
Reputation: 48775
defclass
isn't a function but a macro. It uses the name provided in the source (mode in your case) and it's not the same as your variable mode
. In fact some CL implementations would warn you that argument mode
is never used.
You can macroexpand it (macroexpand '(defclass mode ()()))
to check what it becomes in your implementation. I get this in CLISP (I've cleaned it up a little):
(progn
(eval-when (compile load eval)
(apply #'ensure-class
'mode ; notice mode is quoted
:direct-superclasses (list)
:direct-slots (list)
:metaclass clos::<standard-class>
(append '(:fixed-slot-locations nil)
(list :direct-default-initargs nil
:documentation nil
:generic-accessors 't))))
(find-class 'mode)) ; notice mode is quoted
The expansion is imlementation dependent but the result is the same in all. mode
is the name of the class being defined and not what you pass as argument.
You should use (define-class myclass)
instead of (create-data 'myclass)
.
Upvotes: 3