在CL中,我们有许多运算符来检查依赖于数据类型的相等性:=
,string-equal
,char=
,然后是equal
,{{1}对于其他数据类型,等等,对于比较运算符(编辑,请不要忘记回答这些请求:)我们是否有通用eql
,{{1等等?我们可以让它们为另一个对象工作吗?)
然而,该语言具有使它们成为通用的机制,例如Practical Common Lisp中描述的generics (defgeneric, defmethod)。我非常想象同样的<
运算符,它至少可以处理整数,字符串和字符!
已朝这个方向努力:https://common-lisp.net/project/cdr/document/8/cleqcmp.html
对于初学者(我是其中),我认为这是一个主要的挫折,甚至是一堵墙,特别是我们来自其他语言,如python,我们使用一个相等运算符(>
)来实现每一个平等检查(借助于对象来实现自定义类型)。
今天我指的是a blog post(不是monad教程,很棒的系列)。那个人当然也有其他原因搬到了Clojure,那里有一个(或两个?)运营商。
那为什么会这样呢?有什么好理由吗?我甚至找不到第三方图书馆,甚至连CL21都找不到。 编辑:当然,cl21有这种通用运算符。
关于其他SO问题,我读到了关于表现的问题。首先,这不适用于我写的小代码,所以我不在乎,如果你这么认为,你有没有数字可以说明你的观点?
修改:尽管答案基调如此,但似乎不;)我们在评论中讨论。
答案 0 :(得分:7)
Kent Pitman写了一篇有趣的文章来解决这个问题:The Best of intentions, EQUAL rights — and wrongs — in Lisp。
还要注意EQUAL
对整数,字符串和字符有效。 EQUALP
也适用于列表,向量和散列表以及其他Common Lisp类型但对象......对于某些工作定义。 EQUALP
页面末尾的注释对您的问题有一个很好的答案:
对象相等不是具有唯一确定的正确算法的概念。只能在某些特定程序的需要的背景下判断等式谓词的适当性。虽然这些函数采用任何类型的参数,并且它们的名称听起来非常通用,但是equop和equalp并不适用于每个应用程序。
请特别注意我的上一个“作品”定义中有一个技巧。
答案 1 :(得分:5)
是的,我们有! eq
与所有值一起使用,并且它始终有效。它完全不依赖于数据类型。这正是你要找的。它就像python中的is
运算符。它一定是你想要的?所有其他人在eq
时同意t
,但对于具有不同相似程度的完全不同的值,它们往往是t
。
(defparameter *a* "this is a string")
(defparameter *b* *a*)
(defparameter *c* "this is a string")
(defparameter *d* "THIS IS A STRING")
所有这些都是equalp
,因为它们含有相同的含义。 equalp
也许是最平等的功能。我不认为2和2.0是相同的,但equalp
确实如此。我认为2
是2
而2.0
介于1.95
和2.04
之间。你看他们不一样了。
equal
了解我。 (equal *c* *d*)
绝对是nil
,这很好。但是,它也会为t
返回(equal *a* *c*)
。两者都是字符数组,每个字符都是相同的值,但是这两个字符串不是同一个对象。他们碰巧看起来一样。
注意我在这里使用字符串来表示每一个字符串。我们有4个相同的函数,告诉您两个值是否有共同点,但只有eq
告诉您它们是否相同。
这些都不是特定类型的。它们适用于所有类型,但它们不是泛型,因为它们在语言中添加之前很久就已存在。你可以制作3-4个通用的相同函数,但它们真的会比我们已经拥有的函数更好吗?
答案 2 :(得分:1)
更新的库将通用接口添加到标准Common Lisp函数中:https://github.com/alex-gutev/generic-cl/
GENERIC-CL为Common Lisp标准中的各种功能(例如,相等谓词和序列操作)提供了通用函数包装。包装器的目标是为常见操作(例如测试两个对象的相等性)提供标准接口,该接口可扩展为用户定义的类型。
它用于相等性,比较,算术,对象,迭代器,序列,哈希表,数学函数……
例如,一个人可以定义自己的+
运算符。
答案 3 :(得分:0)
幸运的是CL21引入了(更多)通用运算符,特别是对于它定义length
,append
,setf
,first
,rest
的序列,subseq
,replace
,take
,drop
,fill
,take-while
,drop-while
,last
,{ {1}},butlast
,find-if
,search
,remove-if
,delete-if
,reverse
,reduce
,{{1 }},sort
,split
,join
,remove-duplicates
,every
,some
(还有更多)。不幸的是,文档不是很好,最好看the sources。这些应至少适用于字符串,列表,向量,并定义新map
的方法。
另见