Lisp 为什么';本报价表的评估结果是否符合预期

Lisp 为什么';本报价表的评估结果是否符合预期,lisp,common-lisp,Lisp,Common Lisp,我有一个简单的功能: (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 我很好奇为什么这不会导致“失败”: 我的想法是,与其就地计算funcall,

我有一个简单的功能:

(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
我很好奇为什么这不会导致“失败”:


我的想法是,与其就地计算
funcall
,然后将返回值传递到
ifelse
,不如将整个
funcall
传递到
ifelse
——然而,在函数中如何处理带引号的表单?它本质上不会被就地复制,然后被视为真正的Lisp表单吗?

在本例中,您将列表作为参数传递(因为引用)。 您需要使用eval来评估引用的列表,以获得“失败”。 像这样

(ifelse  (eval '(funcall (lambda () nil))))
或者删除引用

(ifelse  (funcall (lambda () nil)))

在本例中,您将列表作为参数传递(因为引用)。 您需要使用eval来评估引用的列表,以获得“失败”。 像这样

(ifelse  (eval '(funcall (lambda () nil))))
或者删除引用

(ifelse  (funcall (lambda () nil)))

让我们看看你到底得到了什么:

(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
记住,当你引用某物时,你会阻止它被评估


注意:
返回参数
与内置的
标识
的功能相同。我写了一个新的,这样你就可以看到它在引擎盖下做什么了。

让我们看看你到底得到了什么:

(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
记住,当你引用某物时,你会阻止它被评估


注意:
返回参数
与内置的
标识
的功能相同。我写了一个新的,这样你可以看到它在引擎盖下做什么。

我建议不要在这里使用
eval
。首先,您不需要它:为什么您希望传入一个列表,并期望对其进行评估?那太傻了。内置的
if
不能以这种方式工作。您可能会遇到诸如无法访问代码中其他地方定义的变量之类的问题。引用列表不为false的原因不是“因为您需要评估”;原因是“因为你给了它一个列表,而列表是真实的”。我建议不要在这里使用
eval
。首先,您不需要它:为什么您希望传入一个列表,并期望对其进行评估?那太傻了。内置的
if
不能以这种方式工作。您可能会遇到诸如无法访问代码中其他地方定义的变量之类的问题。引用列表不为false的原因不是“因为您需要评估”;原因是“因为你给了它一个列表,而列表是真实的”。