0

我在网上环顾四周,找不到我的查询的答案。如果有人能在不降低这篇文章的评分的情况下提供一个好的答案,我将不胜感激。

在 Lisp中carcdr用于数据模式'(whatever here),这对我来说很有意义。

现在,在Lisp Land of Lisp一书中,作者正在解释如何构建文本引擎,突然他使用以下描述来制作函数。

(defun describe-location (location nodes)
  (cadr (assoc location nodes)))

我能问一下他为什么要在列表上做 cadr 吗?为什么它会提供响应而不是错误?它不应该是一种数据模式,即在左括号前有一个引号'(whatever here)吗?

以及为什么他使用 assoc(assoc location nodes)而不是(assoc 'garden *nodes*)

不是第二种正确的使用方法assoc吗?我可能错过了大局,因此非常感谢有人解释这些关键点。

非常感谢!

4

2 回答 2

3

ASSOC是一个函数。Lisp 计算它的所有参数,然后用这些值调用它。这就是 Lisp 中函数求值的工作方式。

(assoc 'garden *nodes*)
  • Lisp 认为这assoc是一个函数。它现在将评估参数。
  • Lisp 计算'garden为符号garden
  • Lisp 计算*nodes*变量的值*nodes*
  • Lisp 调用assoc这些值。

现在:

(assoc location *nodes*)
  • Lisp 认为这assoc是一个函数。它现在将评估参数。
  • Lisp 计算location变量的值location
  • Lisp 计算*nodes*变量的值*nodes*
  • Lisp 调用assoc这些值。

例如,如果变量的值location是符号garden,则上述assoc表达式返回相同的结果。

于 2014-05-31T07:17:29.987 回答
1

我记得这本书,很有趣。

assoc只返回 cons,其中的 car 等于给定值。这就像find带有参数的函数:key #'car。因此,例如:

CL-USER> (assoc 'a '((a "letter a") (b "letter b") (c "letter c")))
(A "letter a")

因此,既然我们在这里得到了满足测试的整个 cons,car ,我们可以进一步申请cadr这个 cons 并获得相关值:

CL-USER> (cadr (assoc 'a '((a "letter a") (b "letter b") (c "letter c"))))
"letter a"

这都是为了可执行代码。在数据模式下,你只得到列表,而不是表单,所以它不会被执行,你自己试试:

CL-USER> '(car '(a "letter a"))
(CAR '(A "letter a"))

数据模式允许将列表存储为数据,而无需尝试执行它们。这就是为什么作者使用数据模式来定义游戏中房间的描述,但在功能上我们需要执行表单来获得结果。

对于您问题的第二部分,无论如何这只是作者的设计。当然可以放

(assoc 'garden *nodes*)

但它会产生相同的效果,并且仅适用于花园位置。

于 2014-05-31T06:43:01.693 回答