Reputation: 18918
Let's say I define a new class foo
:
(defclass foo ()
((bar :initarg :bar ...)
(baz :initarg :baz ...)
...))
And I want to create a custom comparator for foo
, such as:
(defun foo-equalp (foo1 foo2)
(equalp (bar foo1)))
Would there be a better, more explicit way to tie this foo-equalp
function to the foo
class?
I was thinking of not having to pass #'foo-equalp
as the :test
argument to functions like REMOVE-DUPLICATES
, but even if that is not possible, I would still like to know if there is a more idiomatic Lisp way to define this function.
Upvotes: 0
Views: 361
Reputation: 3231
If I understand your question then generic functions could help here
(defgeneric foo-equalp (foo1 foo2))
(defmethod foo-equalp ((foo1 foo) (foo2 foo))
(and (equal (bar foo1) (bar foo2))
(equal (baz foo1) (baz foo2))))
and now when you call foo-equalp with objects that are not of type foo you get this error.
There is no applicable method for the generic function
#<STANDARD-GENERIC-FUNCTION FOO-EQUALP (1)>
when called with arguments
(1 2).
or you might want everything else to return nil
(defmethod foo-equalp ((foo1 t) (foo2 t))
nil)
Here we specialize on t which is the set of all objects. When you call a method common lisp will always choose the 'closest/most specific' type match for the arguments (ugh that is a terrible mangling of a description..I need more coffee, check out the link as it is awesome :))
The following are snippets from Practical Common Lisp (which is linked at the top of this answer)
A generic function defines an abstract operation, specifying its name and a parameter list but no implementation. The actual implementation of a generic function is provided by methods.
Methods indicate what kinds of arguments they can handle by specializing the required parameters defined by the generic function.
For instance, for a generic function draw, you might define one method that specializes the shape parameter for objects that are instances of the class circle while another method specializes shape for objects that are instances of the class triangle.
Upvotes: 3