使用pop Lisp

时间:2017-03-26 16:19:15

标签: list common-lisp

在测试lisp函数时,我在列表中进行了硬编码。这在使用pop时生成了跟随错误:

(pop '(1 2 3))
  

EVAL:1不是函数名称;尝试使用符号

然而,使用car可以正常工作:

(car'(1 2 3))
> 1

我认为这是因为pop需要一个变量,它可以重新存储列表的其余部分。

如果是这样,当前的错误消息来自哪里,为什么它如此令人难以置信的无益?它甚至没有提到pop是问题所在。

1 个答案:

答案 0 :(得分:6)

预定义的宏pop采用参数而不是列表值,而是place,这是一个评估到某个位置的表单(有关一般说明,请参阅Hyperspec)。例如:

CL-USER> (let ((stack '(1 2 3)))
           (print (pop stack))
           (print stack)
           "Done!")    

1 
(2 3) 
"Done!"

出于错误消息的原因:car将参数作为参数列表,因此'(1 2 3)是一个引用形式,当评估时,会生成列表{{ 1}};最后,(1 2 3)返回此列表的第一个元素1。如果car是宏,而不是函数,则pop形式的扩展类似于:

(pop '(1 2 3))

您可以从中看到列表(LET* ((#:G10655 (1 2 3)) ...) 被评估,这会产生错误消息:

  

EVAL:1不是函数名称;尝试使用符号

实际上,在此评估中,(1 2 3)被视为一个表单,系统会尝试将函数(1 2 3)应用于参数1,这是一个错误,因为{ {1}}不是函数。

无用的消息是典型的带有宏的语言,当错误发生在宏扩展阶段之后:因此使用2 3之类的工具非常有用允许查看此阶段的结果,如@jkiiski在评论中建议的1