Common lisp 用泛型函数替换普通函数

Common lisp 用泛型函数替换普通函数,common-lisp,clos,generic-function,Common Lisp,Clos,Generic Function,我想用elt、nth和mapcar等名称来创建一个新的数据结构,我正在制作原型,但这些名称指定普通函数,因此,我认为,需要重新定义为通用函数 也许重新定义这些名字是不好的形式 有没有办法告诉defgeneric不要生成程序错误并继续替换函数绑定 这些函数不是泛型函数,或者只是历史函数,有什么好的理由吗 请问这里考虑的智慧和最佳实践是什么?如果您使用SBCL或ABCL,并且与ANSI合规性无关,您可以调查可扩展序列: …您不能在COMMON-LISP包中重新定义函数,但可以创建一个新包并对要重

我想用elt、nth和mapcar等名称来创建一个新的数据结构,我正在制作原型,但这些名称指定普通函数,因此,我认为,需要重新定义为通用函数

也许重新定义这些名字是不好的形式

有没有办法告诉defgeneric不要生成程序错误并继续替换函数绑定

这些函数不是泛型函数,或者只是历史函数,有什么好的理由吗


请问这里考虑的智慧和最佳实践是什么?

如果您使用SBCL或ABCL,并且与ANSI合规性无关,您可以调查可扩展序列:

…您不能在COMMON-LISP包中重新定义函数,但可以创建一个新包并对要重新定义的函数的导入进行阴影处理

这些函数不是泛型函数,或者只是历史函数,有什么好的理由吗

CommonLisp在某些领域有一些语言层次。软件的较高级别部分可能需要构建在较低级别的结构上

它的目标之一是速度足够快,适用于各种应用

CommonLisp还引入了序列的概念,即在语言没有对象系统的时候,对列表和向量的抽象。CLOS是在最初的CommonLisp设计之后的几年出现的

举个例子,比如数字相等

Lisp有
=

(= a b)
这是比较数字的最快方法<代码>=也仅为数字定义

然后是
eql
equal
equalp
。这些方法适用于数字,但也适用于其他一些数据类型

现在,如果需要更快的速度,可以声明类型并告诉编译器生成更快的代码:

(locally
  (declare (fixnum a b)
           (optimize (speed 3) (safety 0)))
  (= a b))
那么,为什么
=
不是CLOS通用函数呢

a) 它是在CLO不存在时引入的

但同样重要的是:

b) 在Common Lisp中,不知道(现在仍然不知道)如何在典型使用场景中使CLOS通用函数
=
与非通用函数一样快,同时保持动态类型和可扩展性

CLOS泛型函数只是有一个速度惩罚。运行时调度成本

CLOS最好用于更高级别的代码,这样可以从可扩展性、多分派、继承/组合等特性中获益。泛型函数应该用于定义的泛型行为,而不是作为类似方法的集合

有了更好的实现技术、特定于实现的语言增强等,就有可能增加使用CLOS以高性能方式编写的代码范围。这已经在像Dylan和Julia这样的编程语言中尝试过了

也许重新定义这些名字是不好的形式

普通的Lisp实现不允许您这样替换它们。请注意,替换功能的实现方式应与旧功能一致。此外,旧版本可以以某种方式内联,并且不能在任何地方都可以替换

有没有办法告诉defgeneric不要生成程序错误并继续替换函数绑定

更换时,您需要确保更换件工作正常。代码替换函数可能使用您正在替换的那些函数

尽管如此,实现允许您替换CL函数——但这是特定于实现的。例如,LispWorks提供变量
LispWorks:*用于重新定义时发出警告的包*
LispWorks:*处理重新定义时发出警告*
。我们可以将它们绑定或全局更改

请问,这里公认的智慧和最佳实践是什么

有两种方法:

  • 使用特定于实现的方法替换标准的通用Lisp函数
这可能很危险。另外,您需要为所有要使用的CL实现提供支持

  • 使用定义新语言的语言包。这里是标准的CommonLisp加上您的扩展/更改。导出用户将使用的所有内容。在您的软件中,请使用此软件包而不是
    CL