为什么Common Lisp没有通用运算符?

时间:2017-04-14 17:26:34

标签: common-lisp

在CL中,我们有许多运算符来检查依赖于数据类型的相等性:=string-equalchar=,然后是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问题,我读到了关于表现的问题。首先,这不适用于我写的小代码,所以我不在乎,如果你这么认为,你有没有数字可以说明你的观点?

修改:尽管答案基调如此,但似乎;)我们在评论中讨论。

4 个答案:

答案 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确实如此。我认为222.0介于1.952.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引入了(更多)通用运算符,特别是对于它定义lengthappendsetffirstrest的序列,subseqreplacetakedropfilltake-whiledrop-whilelast,{ {1}},butlastfind-ifsearchremove-ifdelete-ifreversereduce,{{1 }},sortsplitjoinremove-duplicateseverysome(还有更多)。不幸的是,文档不是很好,最好看the sources。这些应至少适用于字符串列表向量,并定义新map的方法。

另见