The following code does what I want:
1 (defclass some-class ()
2 ((some-slot
3 :initarg :somearg
4 :initform (error ":somearg not specified"))))
5 (defparameter *alpha* (make-instance 'some-class :somearg 3))
6 (defparameter *beta* (make-instance 'some-class :somearg 5))
7 (defparameter *gamma* (make-instance 'some-class :somearg 3))
8 (princ (slot-value *beta* 'some-slot)) (terpri)
9 (defparameter *delta* (list *alpha* *beta* *gamma*))
10 (princ *delta*) (terpri)
11 (princ (remove-duplicates *delta*
12 :test #'equal
13 :key (lambda (x) (slot-value x 'some-slot))))
14 (terpri)
5
(#<SOME-CLASS #x21C1D71E> #<SOME-CLASS #x21C1DAFE> #<SOME-CLASS #x21C1DC3E>)
(#<SOME-CLASS #x21C1DAFE> #<SOME-CLASS #x21C1DC3E>)
But is there a way to do this without having to write the function on line 13? Is there a shorthand way to specify as the key a slot value in the class instance?
The following blows up with a syntax error, of course, but it gives the general idea of what I'm seeking.
1 (princ (remove-duplicates *delta*
2 :test #'equal
3 :key '(slot-value 'some-slot)))
4 (terpri)
*** - FUNCALL: (SLOT-VALUE 'SOME-SLOT) is not a function name; try using a
symbol instead
You could try a
:reader
or:accessor
.Doing
should let you re-write lines 11 through 13 as
That is,
(some-slot x)
is equivalent to(slot-value x 'some-slot)
if the slot in question has a reader/accessor.After-Sleep Edit:
You also don't need to bother setting
:initform
to error; a slot will do that by default if you don't specify a default value and someone tries to read it. If you don't want the error, you do something like:initform nil
. Check out this excellent CLOS tutorial as well as chapters 16 and 17 of Practical Common Lisp for more information about objects in Common Lisp.Also, in the future if you have working code that you'd like style advice on, do check out codereview.stackexchange. There's a small, but active population of Lisp reviewers.