Specifying a slot value as a key when deleting duplicates

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 a function on line 13? Is there an abbreviated way to specify the key value of the slot in the class instance?

The following explosions with a syntax error, of course, but this gives a general idea of ​​what I'm looking for.

  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 
+4
source share
2 answers

You can try :reader or :accessor .

Performance

 (defclass some-class () ((some-slot :initarg :somearg :reader some-slot :initform (error ":somearg not specified")))) 

should allow you to rewrite lines 11 through 13 as

 (princ (remove-duplicates *delta* :test #'equal :key #'some-slot)) 

That is, (some-slot x) equivalent to (slot-value x 'some-slot) if this slot has a reader / accessor.


Editing after sleep:

You also do not need to worry about the error :initform ; the slot will do this by default unless you specify a default value and someone tries to read it. If you don't want an error, you do something like :initform nil . Check out this excellent CLOS tutorial , as well as chapters 16 and 17 Practical General Lisp for more information on objects in Common Lisp.

Also, in the future, if you have working code that you would like to recommend a style for, look at codereview.stackexchange . There is a small but active population of Lisp reviewers.

+3
source

You can define a read function for a slot in defclass and provide this as a key function for remove-duplicates . For example, add this line to the slot definition:

 :reader some-slot 

and then use this in the remove-duplicates call:

 :key #'some-slot 
+2
source

Source: https://habr.com/ru/post/1393564/


All Articles