嵌套的`defun`在Allegro Common Lisp中产生重复警告 [英] Nested `defun` produces a repeated warning in Allegro Common Lisp

查看:174
本文介绍了嵌套的`defun`在Allegro Common Lisp中产生重复警告的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Common Lisp中有一个通用的归类排序实现:我对split和merge函数有不同的实现,并且对于split和merge函数的每个组合,我都想构造一个归类排序函数.

I have a generic implementation of merge sort in Common Lisp: I have different implementation of split and merge functions and, for each combination of a split and merge function I want to construct a merge sort function.

  • 任何split函数都将字符串列表作为输入,并返回两个列表的列表:原始列表的两半.
  • 任何合并功能都将两个排序后的列表作为输入,并返回排序后的合并后的列表.

通过调用以下函数来创建每个合并排序函数:

Each merge sort function is created by invoking the following function:

(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)))

我在make-merge-sort-function内定义了merge-sort,以保持其名称私密并避免破坏名称空间.

I have defined merge-sort inside make-merge-sort-function in order to keep its name private and avoid spoiling the name space.

我的代码可用于几种Common Lisp实现(例如Steel Bank Common Lisp):

My code works with several Common Lisp implementations (e.g. Steel Bank Common Lisp):

  • 我所有测试运行的输出均已正确排序
  • 每个结果合并排序函数的执行时间都不同,这表明使用了不同的拆分/合并组合.

所以,我认为我的代码是正确的.

So, I assume that my code is correct.

但是,如果我使用Allegro Common Lisp运行该程序,则会收到警告:

However, if I run the program with Allegro Common Lisp, I get a warning:

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-functionmerge-function),则警告消失.

where foo.lisp is the file in which make-merge-sort-function is invoked. So, the program works fine but it prints this warning once for each invocation of make-merge-sort-function after the first one. If I make the merge-sort function global (with two additional arguments split-function and merge-function), then the warnings go away.

我在Allegro Common Lisp中未发现有关此警告含义的任何迹象.我尝试过的其他实现(ABCL,CMUCL,CCL,CLISP,SBCL)不会发出任何警告.我认为可以多次定义内部函数(关闭)的新实例,这是可以的,但我不明白为什么这应该是一个问题. 有什么想法吗?

I have not found any indication regarding the meaning of this warning in Allegro Common Lisp. Other implementations I have tried (ABCL, CMUCL, CCL, CLISP, SBCL) do not issue any warning. I think it is OK that a fresh instance of the internal function (closure) is defined multiple times and I do not understand why this should be a problem. Any ideas?

推荐答案

从不嵌套 defun .

就像您在内部使用 let defun 代替 defvar ,您可以使用 labels 代替 的嵌套 defun :

Just like you use let inside defun instead of defvar, you use labels instead of nested defun:

(defun make-merge-sort-function (split-function merge-function)
  (labels ((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)))))))
    #'merge-sort))

这篇关于嵌套的`defun`在Allegro Common Lisp中产生重复警告的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆