Lisp 函数命名空间

Lisp function namespaces

我想弄清楚 Common Lisp 是如何处理函数的。如果我做类似

(defun square (n)
  (* n n))

我可以稍后打电话,例如(square 10)。但是,如果我做类似

(defun reapply (fun)
  (lambda (n)
    (funcall fun (funcall fun n))))

然后定义

(defparameter to-the-fourth (reapply #'square))

第四个函数不能调用(to-the-fourth 10);我不得不写 (funcall to-the-fourth 10)。我认为那是因为 defparameter 在变量命名空间而不是函数命名空间中定义变量。有没有办法在函数命名空间中定义函数?以下内容似乎很冗长:

(defun to-the-fourth (a)
  (funcall (reapply #'square) a))

首先,两个错别字:

(defun reapply (fun)
  (lambda (n) (funcall fun (funcall fun (n)))

应该是

(defun reapply (fun)
  (lambda (n) (funcall fun (funcall fun n))))

(defparameter to-the-fourth (reapply square))

应该是

(defparameter to-the-fourth (reapply #'square))

(或者,*to-the-fourth*,因为命名特殊变量的两边都带有星号是很常见的。)这里的 #' 表明您想要与符号关联的函数。

你要的是

(setf (symbol-function 'to-the-fourth) (reapply #'square))

您可以通过这种方式直接编辑与符号关联的函数。不过风格不是很好

您的版本与 vukung 的版本之间的差异之一是 延迟绑定:

CL-USER 1 > (defun square (n)
              (* n n))
SQUARE

CL-USER 2 > (defun reapply (fun)
              (lambda (n)
                (funcall fun (funcall fun n))))
REAPPLY

CL-USER 3 > (defun to-the-fourth (a)
              (funcall (reapply #'square) a))
TO-THE-FOURTH

CL-USER 4 > (to-the-fourth 10)
10000

CL-USER 5 > (defun square (n)
              (* n n 2))
SQUARE

CL-USER 6 > (to-the-fourth 10)
80000

在这种情况下,函数 to-the-fourth 调用 square 的当前定义。通常是这种情况 -> 除非优化编译器正在内联函数。

将其与我们处理函数对象的版本进行比较:

CL-USER 7 > (setf (symbol-function 'to-the-fourth)
                  (reapply #'square))
#<anonymous interpreted function 70D00015DC>

CL-USER 8 > (to-the-fourth 10)
80000

CL-USER 9 > (defun square (n)
              (* n n))
SQUARE

CL-USER 10 > (to-the-fourth 10)
80000

这个总是调用定义时间的版本。