2013-11-22 52 views
0

比方说,我定义一个新类fooLisp的自定义比较函数

(defclass foo() 
    ((bar :initarg :bar ...) 
    (baz :initarg :baz ...) 
    ...)) 

我想创建一个自定义的比较为foo,如:

(defun foo-equalp (foo1 foo2) 
    (equalp (bar foo1))) 

会不会有更好的,更明确的方式来把这些foo-equalp功能将foo类?

我想不必通过#'foo-equalp:test参数的功能,如REMOVE-DUPLICATES的,但即使这是不可能的,我还是想知道是否有定义该功能的更地道Lisp的方式。

+0

听起来好像你想要一个相等谓词,它是一个可以添加专门方法的通用函数(有点像你可以在Java中专注于'.equals()')。不幸的是,没有一个“常见”谓词('eq','eql','equal','equalp')是泛型函数,所以尽管编写这样的泛型函数并不难,但仍然必须通过它去像'remove'等库函数,因为它不会是这些库函数的默认比较。 –

+0

@JoshuaTaylor:你知道http://cdr.eurolisp.org/document/8/cleqcmp.html吗?我已经完成了CDR8的实现,但尚未发布(需要清理并提交它)。 –

+0

@PaulNathan我意识到CDR存储库,但是我以前没有读过那个。这看起来不错。我肯定会赞成使用它的答案。 :)我意识到你说过你还没有发布它,但它可以在任何地方在任何状态下在线吗? –

回答

3

如果我明白你的问题,然后generic functions可以帮助这里

(defgeneric foo-equalp (foo1 foo2)) 

(defmethod foo-equalp ((foo1 foo) (foo2 foo)) 
    (and (equal (bar foo1) (bar foo2)) 
     (equal (baz foo1) (baz foo2)))) 

,现在当你调用foo-equalp与是Foo类型的对象不是你得到这个错误。

There is no applicable method for the generic function 
    #<STANDARD-GENERIC-FUNCTION FOO-EQUALP (1)> 
when called with arguments 
    (1 2). 

,或者您可能希望一切回到零

(defmethod foo-equalp ((foo1 t) (foo2 t)) 
    nil) 

在这里,我们专注于t which is the set of all objects。当你调用一个方法的Common Lisp总是会选择最亲密的/最具体的“类型的参数匹配(啊这是一个description..I的可怕的mangling需要更多的咖啡,检查出的链接,因为它是真棒:)

  • 你实际上并不需要专门的T,因为这是默认的,但我想包括它显示发生了什么事。

以下是从实践的Common Lisp

通用函数定义抽象操作(其在此 答案的顶部连接的),代码段指定其名称 和参数列表,但没有实现。泛型函数的实际实现 由方法来提供。

方法表明,他们可以通过 处理专门由泛型函数定义的参数需要什么样的参数。

例如,对于一个泛型函数平局,你可以定义一个方法 ,专门为是 情况下,类圆而另一种方法专门针对那些类三角形的实例对象 形状的物体形状参数。

+2

当您计划使用继承和/或方法组合使用多种方法扩展它时,请使用泛型函数。否则,它可能是矫枉过正。 –

+0

干杯,我一直对何时选择哪种技术感到朦胧。很高兴有这个经验法则。 – Baggers