我一直在读《小谋士》的第一章。问题是,有些例子像 DrRacket 一样工作(eq? "foo" "foo")
,有些不喜欢(car ("a" "b"))
或(cdr ("a" "b"))
因为
application: not a procedure;
expected a procedure that can be applied to arguments
given: "a"
arguments...:
你能指出我为什么这些例子不起作用吗?
我一直在读《小谋士》的第一章。问题是,有些例子像 DrRacket 一样工作(eq? "foo" "foo")
,有些不喜欢(car ("a" "b"))
或(cdr ("a" "b"))
因为
application: not a procedure;
expected a procedure that can be applied to arguments
given: "a"
arguments...:
你能指出我为什么这些例子不起作用吗?
这些示例不起作用,因为它们不是合法的方案。我对这本书不熟悉,但可能是它的排版方式可能会导致在不犯错误的情况下从其中转录示例有点困难。要了解为什么它们不是,您需要考虑系统如何评估事物。这是关于它如何工作的简单而部分的描述(实际的实现做的事情比这要复杂得多,而且这个描述是部分的,尤其是因为它根本没有解释我们如何获得事物的绑定)。
评估某事:
(foo ...)
吗?如果是,那么——
所以我们可以使用这些规则来尝试评估(car ("a" "b"))
。
car
不是什么特殊的东西,所以我们不打那个案子;car
是一个符号,所以查找它的值是一个函数;("a" "b")
是复合形式,它的第一个元素并不特殊——
好的,所以这行不通。为了使它起作用,我们需要返回并查看评估规则中的一个案例:当评估一个复合形式时,我们偷偷看一下第一个元素,以确定它是否是我们所知道的一些特殊的魔法事物,在这种情况下,我们会做一些特别的东西。这种特殊魔法的东西很少:我们这里唯一关心的是quote
。对此的特殊规则是:
quote
,它看起来像(quote ...)
,那么——
(quote <x>)
一些<x>
;<x>
没有进一步尝试评估<x>
表格的价值。因此,例如:
(quote x)
是符号x
;(quote (1 2 3))
是列表(1 2 3)
;(quote "x")
是字符串"x"
(在这种情况下你不需要quote
,因为字符串已经通过上面的第一条规则对自己进行评估,但它没有伤害)。所以回到我们想要评估的形式,我们真正需要的是(car (quote ("a" "b")))
. 在评估这个时:
car
不是什么特殊的东西,所以我们不打那个案子;car
是一个符号,所以查找它的值是一个函数;(quote ("a" "b"))
是复合形式——
quote
;quote
结果是("a" "b")
;car
to的值("a" "b")
,结果是"a"
。所以还有一个技巧:经常(quote <x>)
出现,所以它有一个特殊的语法,它是一个单一的'
:与 .'x
读取相同(quote x)
。这只是使源代码不那么冗长。所以这给出了你正在尝试做的工作版本的最终形式:
(car '("a" "b"))
最后,Lisps需要 quote
的原因是一件有趣的事情,但与这个答案无关。