0

我有一个简单的功能:

(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

我的想法是,与其评估funcallin 到位然后将返回值传递给,不如ifelse将整个funcall传递到未评估的ifelse- 但是,如何在函数中处理带引号的形式?它不会本质上被原地复制,然后被视为真正的 Lisp 形式吗?

4

2 回答 2

4

让我们看看你实际得到了什么:

(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。我写了一个新的,所以你可以看到它在引擎盖下做了什么。

于 2013-11-01T07:09:46.457 回答
0

In the example , you pass a list as argument (because of the quote). You need to use eval to evaluate the quoted list to have the 'failure'. like this

(ifelse  (eval '(funcall (lambda () nil))))

or remove the quote

(ifelse  (funcall (lambda () nil)))
于 2013-11-01T07:08:18.747 回答