如果 CLOS 有一个编译时分派,这个代码片段会发生什么?

If CLOS had a compile-time dispatch, what would happen to this code snippet?

我正在阅读有关 CLOS 的维基百科文章。

上面写着:

This dispatch mechanism works at runtime. Adding or removing methods thus may lead to changed effective methods (even when the generic function is called with the same arguments) at runtime. Changing the method combination also may lead to different effective methods.

然后,我插入:

; declare the common argument structure prototype
(defgeneric f (x y))

; define an implementation for (f integer t), where t matches all types
(defmethod f ((x integer) y) 1)

使用 SBCL 和 SLIME,我用代码编译了区域并得到了以下结果:

CL-USER> (f 1 2)
1

然后,我在定义中添加了:

; define an implementation for (f integer real)
(defmethod f ((x integer) (y real)) 2)

再次,我重复了编译新区域并使用 REPL 进行评估的过程:

CL-USER> (f 1 2.0)

2

第一个问题,如果 CLOS 具有与 运行 时间调度(我想是编译时调度)相反的行为,结果会是什么?

第二个问题,我决定把第二个方法注释掉,只留下泛型函数和第一个写的方法。然后,我用Emacs重新编译了这个区域。

当使用 (f 1 2) 在 REPL 中调用函数 f 时,我想我会得到 1,因为第二种方法已经过时了。相反,我得到了 2.

CL-USER> (f 1 2.0)

2

为什么会这样?

我可以返回 (f 1 2) 返回 1 的唯一方法是重新启动 Slime REPL 并编译该区域(第二种方法被注释掉)。第三个问题,有没有更好的方法不用重启REPL就可以得到这个结果?

谢谢!

这两个其实是同一个问题。答案是:你在运行ning.

时修改系统
  1. 如果 CLOS 对象不是 re-definable 在 run-time,这根本行不通,否则您将不被允许这样做。尝试这样的 re-definitions 和基本结构(即使用 defstruct 时得到的东西),并且当更改不兼容时,您经常会 运行 进入非常严重的警告甚至错误。当然,结构也有其他限制,例如。 G。只有一次分派,所以做一个完全类似的例子并不那么容易。但是尝试从 defstruct 中删除一个插槽。

  2. 只是注释掉一些源代码并不能改变您之前评估(编译和加载)它的事实。您正在操纵一个 运行ning 系统,而源代码就是:源代码。如果要从 运行ning 系统中删除方法,可以使用 remove-method(另请参阅 )。大多数 Lisp IDE 都有交互方式来做到这一点,例如。 G。在 SLIME 中使用 SLIME 检查器。