我遇到了Common Lisp中的以下问题(使用CLISP)...以下代码运行正常且符合预期(' - >'指定函数调用返回的内容):
(list (quote x)) -> (X)
但是,当我尝试将此行为移动到函数中时,
(defun quote-it (x)
(list (quote x)))
我调用该函数,出现意外错误。
(quote-it x) -> SYSTEM::READ-EVAL-PRINT: variable X has no value
有谁能解释这里发生了什么?
感谢。
答案 0 :(得分:4)
如果您编译quote-it
,您将收到一条警告,指出您没有使用参数x
的值。这可以作为一个警告,说明有些不妥。
具体来说,Common Lisp evaluates使用(quote-it x)
表达式,首先评估x
,然后将结果传递给quote-it
。由于您从未向x
提供值,因此第一步失败。
试试这些:
(defparameter x 42)
(quote-it x)
==> (x)
(quote-it 'y)
==> (x)
如您所见,传递给quote-it
的内容并不重要。
PS:一般来说,特殊运算符quote
很少用于函数。不过,正如评论者所建议的那样,它是宏中的常用工具:
(defmacro quote-it (x) `(list ',x))
如果您告诉我们想要实现的目标(在另一个问题中),我们(SO社区)可能会提供更多帮助。
答案 1 :(得分:0)
首先评估(QUOTE-IT X)
。
为此,它评估X
。
X
没有价值。
您可以在 backtrace 或步进器中轻松看到这一点:
CLISP Backtrace。
Break 1 [5]> :bt
<1/153> #<SYSTEM-FUNCTION SHOW-STACK> 3
<2/146> #<COMPILED-FUNCTION SYSTEM::PRINT-BACKTRACE>
<3/140> #<COMPILED-FUNCTION SYSTEM::DEBUG-BACKTRACE>
<4/131> #<SYSTEM-FUNCTION SYSTEM::READ-EVAL-PRINT> 2
<5/128> #<COMPILED-FUNCTION SYSTEM::BREAK-LOOP-2-3>
<6/124> #<SYSTEM-FUNCTION SYSTEM::SAME-ENV-AS> 2
<7/110> #<COMPILED-FUNCTION SYSTEM::BREAK-LOOP-2>
<8/108> #<SYSTEM-FUNCTION SYSTEM::DRIVER>
<9/68> #<COMPILED-FUNCTION SYSTEM::BREAK-LOOP>
<10/65> #<SYSTEM-FUNCTION INVOKE-DEBUGGER> 1
<11/55> #<SYSTEM-FUNCTION ERROR>
<12/42> #<COMPILED-FUNCTION SYSTEM::CHECK-VALUE>
[39] EVAL frame for form X
[34] EVAL frame for form (QUOTE-IT X)
CLISP步进
[10]> (step (quote-it x))
step 1 --> (QUOTE-IT X)
Step 1 [11]> :s ; <--- STEP
step 2 --> X
Step 2 [12]> :S ; <--- STEP
*** - EVALHOOK: variable X has no value
The following restarts are available:
USE-VALUE :R1 Input a value to be used instead of X.
STORE-VALUE :R2 Input a new value for X.
ABORT :R3 Abort main loop