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
这个总是调用定义时间的版本。
我想弄清楚 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
这个总是调用定义时间的版本。