我有一个简单的函数:
(defun ifelse (the-test)
(cond (the-test (format t "passed test, true!"))
(t (format t "failed test, boo hoo"))))
如果我这样做,我会得到你所期望的:
(ifelse (funcall (lambda () nil)))
failed test, boo hoo
NIL
我很好奇为什么这不会导致“失败”:
CL-USER> (ifelse '(funcall (lambda () nil)))
passed test, true!
NIL
我的想法是,不是就地评估funcall
,然后将返回值传递给ifelse
,而是整个funcall
传递给 ifelse
未评估——但是,如何在函数中处理引用形式?它不会本质上被就地复制,然后被视为真正的 Lisp 形式吗?
最佳答案
让我们看看您实际得到了什么:
(defun return-argument (element) element)
[9]> (defun return-argument (element) element)
RETURN-ARGUMENT
[10]> (return-argument (funcall (lambda () nil)))
NIL
好的,这符合预期。现在是您的第二个函数调用,它导致失败。
[11]> (return-argument '(funcall (lambda () nil)))
(FUNCALL (LAMBDA NIL NIL))
啊哈,这给了我们一个线索。我们不评估论点,因为它被引用了。事实上,我们可以看到我们将其作为列表取回:
[19]> (listp (return-argument '(funcall (lambda () nil))))
T
请记住,当您引用某些内容时,您会阻止对它进行评估。
注意:return-argument
与内置的identity
功能相同。我写了一个新的,这样你就可以看到它在做什么。
关于lisp - 为什么这个引用的表格没有按预期评估,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19722240/