Common Lisp函数命名空间规则与函数对象绑定方法问询
Common Lisp 函数命名空间绑定问题解答
你的推测完全正确:Common Lisp 是典型的 Lisp-2 方言,同一个符号的变量绑定和函数绑定分属两个完全独立的命名空间:
defvar/defparameter只会修改符号的变量命名空间绑定- 表达式中第一个位置的符号,求值时会优先去函数命名空间找绑定,所以你用
defparameter绑定的to-the-fourth直接作为调用头会找不到函数定义,必须用funcall读取变量值里的函数对象再执行。
最简洁的原生解决方法
直接用Common Lisp内置的fdefinition访问函数命名空间,单次绑定即可永久生效:
(setf (fdefinition 'to-the-fourth) (reapply #'square))
绑定完成后就可以直接调用(to-the-fourth 10)得到结果10000,不需要加funcall。
这种写法比你目前用的defun包裹的写法还有额外的性能优势:你现在的写法每次调用to-the-fourth时都会重新执行(reapply #'square)生成新的lambda对象,而fdefinition的写法只会执行一次reapply,把生成的函数对象直接绑定到函数命名空间,不会有重复计算开销。
高频使用场景的简化封装
如果你经常需要做这类高阶函数返回值的函数命名空间绑定,可以自己定义一个简单的宏简化写法:
(defmacro defun-f (name fun-expr) `(setf (fdefinition ',name) ,fun-expr))
之后就可以用更短的语句完成绑定:
(defun-f to-the-fourth (reapply #'square))
内容的提问来源于stack exchange,提问作者Andrew Mackenzie
相关产品推荐
相关产品推荐

