Common lisp 我可以通过它在函数名称空间中定义函数吗';s值多少?

Common lisp 我可以通过它在函数名称空间中定义函数吗';s值多少?,common-lisp,Common Lisp,我最近开始学习CL,我试图弄清楚是否可以在函数名称空间中为符号设置一个值 我只想根据函数组合定义函数,或者简单地通过现有函数定义函数(例如,在一个玩具“Hello,World!”级别的项目中,我只需重写identity两次)。我不确定这是否可能,因为它可能会打破名称空间分离(至少在没有强制的情况下)。我还尝试了macro扩展defun的实际功能;作为初学者,它对我来说太神秘了,但它的核心部分似乎是内置的(我正在使用SBCL) 因此,例如,不要说: (defun myfn (x) x) 我宁愿说

我最近开始学习CL,我试图弄清楚是否可以在函数名称空间中为符号设置一个值

我只想根据函数组合定义函数,或者简单地通过现有函数定义函数(例如,在一个玩具“Hello,World!”级别的项目中,我只需重写
identity
两次)。我不确定这是否可能,因为它可能会打破名称空间分离(至少在没有强制的情况下)。我还尝试了
macro扩展
defun
的实际功能;作为初学者,它对我来说太神秘了,但它的核心部分似乎是内置的(我正在使用SBCL)

因此,例如,不要说:

(defun myfn (x) x)
我宁愿说:

(def..? myfn identity)

如果我不能做到这一点,如何避免此类代码重复?(包括通过函数组合创建的函数,而不仅仅是创建同义词)。

在当前环境中,对于绑定到符号的函数,这是可能的:

还有
(setf fdefinition)
,其功能大致相同,但也支持
setf
功能

对于词汇绑定函数(通过
FLET
LABELS
)不能这样做

如何使用
(setf fdefinition)
设置符号函数的示例

CL-USER 11 > (setf (fdefinition 'myfn) #'identity)
#<Function IDENTITY 410003F974>

CL-USER 12 > (myfn 10)
10
可能会被类似于

(eval-when (:compile-toplevel :load-toplevel :execute)
  (setf (fdefinition 'myfn) #'identity))
优点:在编译过程中,该函数将像往常一样为人所知

要记住的一件事是:

符号对象可能携带一些信息。例如,原始函数名,如果有:

CL-USER 13 > #'identity
#<Function IDENTITY 410003F974>
自递归函数也有一个问题:

CL-USER 19 > (defun foo (n)
               (if (zerop n)
                   1
                 (* n (foo (1- n)))))  ; here foo calls the function foo
FOO
现在,我们将
BAR
设置为使用函数
FOO

CL-USER 20 > (setf (symbol-function 'bar) #'foo)
#<interpreted function FOO 4060004084>


CL-USER 21 > (bar 10)
3628800
BAR
仍然使用旧的
FOO
,它可以调用新的
FOO

CL-USER 23 > (bar 10)
460
哎呀!我们更改了FOO,但它对BAR有奇怪的影响:第一次迭代是旧的FOO,下一次递归调用是新的FOO

BAR
FOO
是同一功能的两个不同版本。但两者都调用函数
FOO
,这可能是旧函数,也可能是新函数,具体取决于您如何解释或编译代码

CL-USER 24 > #'foo
#<interpreted function FOO 40600041F4>

CL-USER 25 > #'bar
#<interpreted function FOO 4060004084>
CL-USER 24>#'foo
#
CL-USER 25>#栏
#

这只是一个想法,您可以添加一个宏,扩展到
(defun myfun(&rest args)(apply identity args))
。当然,在Lisp-1中,您可以只使用
(定义myfn标识)
。一定要查看从副本链接的一些函数。到处都是有用的信息。题为为什么defun与(setq)不一样?有一些很好的讨论。另外,为了清楚起见,您可以使用
#“
表示法获得符号的函数值。也就是说,您不需要执行
(let((id(lambda(x)x)))(compose id…)
。你可以只做
(让((id#'identity))(编写id…)
(编写#'identity…)
CL-USER 19 > (defun foo (n)
               (if (zerop n)
                   1
                 (* n (foo (1- n)))))  ; here foo calls the function foo
FOO
CL-USER 20 > (setf (symbol-function 'bar) #'foo)
#<interpreted function FOO 4060004084>


CL-USER 21 > (bar 10)
3628800
CL-USER 22 > (defun foo (n)
               (if (zerop n)
                   1
                 (+ n (foo (1- n)))))
FOO
CL-USER 23 > (bar 10)
460
CL-USER 24 > #'foo
#<interpreted function FOO 40600041F4>

CL-USER 25 > #'bar
#<interpreted function FOO 4060004084>