Ano*_*ous 5 lisp clisp common-lisp
我正在从"Practical Common Lisp"一书中学习Lisp.有一次,我应该输入以下代码:
[1] (remove-if-not #'evenp '(1 2 3 4 5 6 7 8 9 10))
(2 4 6 8 10)
Run Code Online (Sandbox Code Playgroud)
我想这里的想法当然是remove-if-not想要一个在向它提供参数时可以返回T或NIL的函数,然后将该函数应用于列表中的所有符号,返回仅包含列表的列表那些返回NIL的符号.
但是,如果我现在在CLISP中编写以下代码:
[2] (remove-if-not 'evenp '(1 2 3 4 5 6 7 8 9 10)
(2 4 6 8 10)
Run Code Online (Sandbox Code Playgroud)
它仍然有效!所以我的问题是,是否使用尖引号表示法,或仅仅使用引用是否足够?现在看起来额外的锐利只是让程序员知道"嘿,这是一个功能,而不仅仅是一些随机的符号!" - 但如果它有任何其他用途,我很想知道它.
我使用的是GNU CLISP 2.49(2010-07-07,sheesh,实际上很老).
gsg*_*gsg 13
在一般情况下,尖锐报价和报价不具有相同的行为:
(defun test () 'red)
(flet ((test () 'green))
(list (funcall 'test)
(funcall #'test))) => (red green)
Run Code Online (Sandbox Code Playgroud)
调用带引号的符号将使用带引号的符号的函数值(即结果symbol-function).调用带尖括号的符号将使用符号的词法绑定(如果有)所建立的值.在公认的常见情况下,没有词汇绑定,行为将是相同的.这就是你所看到的.
你应该养成使用尖锐引用的习惯.忽略函数绑定可能不是您想要的,并且可能会让任何试图理解您的代码的人感到困惑.
这不是特定于CLISP的,它适用于每个Common Lisp实现(我在这里使用Clozure Common Lisp).
会发生的是,如果您将符号作为函数指示符,那么实现将为您查找symbol-function(假设符号在全局环境中可用):
? #'evenp
#<Compiled-function EVENP #x3000000F2D4F>
? (symbol-function 'evenp)
#<Compiled-function EVENP #x3000000F2D4F>
Run Code Online (Sandbox Code Playgroud)
一般来说,您可以使用其中之一,但如果您稍后重新绑定被调用函数,则会产生一个有趣的效果.如果指定函数(#'或(function)),则调用仍将调用旧函数,因为查找已在编译时完成; 如果您使用该符号,那么您将调用新函数,因为查找是在运行时重新完成的.请注意,这可能是特定于实现的.