我想将 elt、nth 和 mapcar 之类的名称与我正在原型设计的新数据结构一起使用,但是这些名称指定了普通函数,因此我认为需要将其重新定义为通用函数。
重新定义这些名称大概是不好的形式?
有没有办法告诉 defgeneric 不要产生程序错误并继续替换函数绑定?
这些不是通用功能还是只是历史性的,有充分的理由吗?
请问这里被认为的智慧和最佳实践是什么?
我想将 elt、nth 和 mapcar 之类的名称与我正在原型设计的新数据结构一起使用,但是这些名称指定了普通函数,因此我认为需要将其重新定义为通用函数。
重新定义这些名称大概是不好的形式?
有没有办法告诉 defgeneric 不要产生程序错误并继续替换函数绑定?
这些不是通用功能还是只是历史性的,有充分的理由吗?
请问这里被认为的智慧和最佳实践是什么?
如果您使用的是 SBCL 或 ABCL,并且不关心 ANSI 合规性,则可以调查可扩展序列:
http://www.sbcl.org/manual/#Extensible-Sequences
http://www.doc.gold.ac.uk/~mas01cr/papers/ilc2007/sequences-20070301.pdf
...您不能在 COMMON-LISP 包中重新定义函数,但您可以创建一个新包并隐藏要重新定义的函数的导入。
这些不是通用功能还是只是历史性的,有充分的理由吗?
Common Lisp 在它的某些领域有一些语言层次。软件的高级部分可能需要建立在低级结构上。
它的一个目标是对一系列应用程序足够快。
当语言没有对象系统时,Common Lisp 还引入了序列的概念,即对列表和向量的抽象。CLOS 是在最初的 Common Lisp 设计之后几年出现的。
举个例子,比如平等——对于数字。
Lisp 有=
:
(= a b)
这是比较数字的最快方法。=
也只为数字定义。
然后有eql
和。这些适用于数字,但也适用于其他一些数据类型。equal
equalp
现在,如果您需要更快的速度,您可以声明类型并告诉编译器生成更快的代码:
(locally
(declare (fixnum a b)
(optimize (speed 3) (safety 0)))
(= a b))
那么,为什么=
不是 CLOS 泛型函数呢?
a) 在 CLOS 不存在时引入
但同样重要:
b) 在 Common Lisp 中,不知道(现在仍然不知道)如何使 CLOS 泛型函数=
与典型使用场景的非泛型函数一样快——同时保留动态类型和可扩展性
CLOS 泛型函数只是有速度损失。运行时调度成本。
CLOS 最适合用于更高级别的代码,然后真正受益于可扩展性、多调度、继承/组合等特性。泛型函数应该用于定义的泛型行为——而不是作为类似方法的集合。
借助更好的实现技术、特定于实现的语言增强等,可能会增加可以使用 CLOS 以高性能方式编写的代码范围。这已经在 Dylan 和 Julia 等编程语言中进行了尝试。
重新定义这些名称大概是不好的形式?
Common Lisp 实现不允许你替换它们。请注意,您的替换功能应该以与旧功能一致的方式实现。此外,旧版本可以以某种方式内联,并且不能在任何地方替换。
有没有办法告诉 defgeneric 不要产生程序错误并继续替换函数绑定?
您需要确保在更换时更换工作正常。代码替换功能,可能会使用您要替换的那些功能。
尽管如此,实现仍允许您替换 CL 函数 - 但这是特定于实现的。例如 LispWorks 提供了变量lispworks:*packages-for-warn-on-redefinition*
和lispworks:*handle-warn-on-redefinition*
. 可以绑定它们或全局更改它们。
请问这里被认为的智慧和最佳实践是什么?
有两种方法:
这可能很危险。另外,您需要为要使用的所有 CL 实现支持它...
CL
.