我在 Common Lisp 中有一个通用的合并排序实现:我有不同的拆分和合并函数实现,并且对于拆分和合并函数的每个组合,我想构造一个合并排序函数。
- 任何拆分函数都将字符串列表作为输入并返回两个列表的列表:原始列表的两半。
- 任何合并函数都将两个排序列表作为输入并返回排序后的合并列表。
每个归并排序函数都是通过调用以下函数创建的:
(defun make-merge-sort-function (split-function merge-function)
(defun merge-sort (lst)
(if (or (null lst) (null (cdr lst)))
lst
(let ((s (funcall split-function lst)))
(funcall merge-function (merge-sort (car s)) (merge-sort (cadr s))))))
(lambda (lst)
(merge-sort lst)))
我在merge-sort
里面定义make-merge-sort-function
是为了保持它的名字私有并避免破坏命名空间。
我的代码适用于几个 Common Lisp 实现(例如 Steel Bank Common Lisp):
- 我所有测试运行的输出都正确排序,
- 每个生成的合并排序函数都有不同的执行时间,表明使用了不同的拆分/合并组合。
所以,我假设我的代码是正确的。
但是,如果我使用 Allegro Common Lisp 运行程序,我会收到警告:
Warning: MERGE-SORT is defined more than once as `operator' in file foo.lisp.
调用foo.lisp
的文件在哪里。make-merge-sort-function
因此,该程序工作正常,但它会在第一次调用之后的每次调用时打印一次此警告make-merge-sort-function
。如果我将merge-sort
函数设为全局函数(带有两个附加参数split-function
和merge-function
),那么警告就会消失。
我没有在 Allegro Common Lisp 中找到有关此警告含义的任何指示。我尝试过的其他实现(ABCL、CMUCL、CCL、CLISP、SBCL)不会发出任何警告。我认为可以多次定义内部函数(闭包)的新实例,但我不明白为什么这应该是一个问题。有任何想法吗?