1

最近在看 Paul Graham 的文章《Root Of Lisp》,遇到了一些问题。从书中,将表达式定义为两个 :1.atom;2.list,而 list 由零个或多个表达式组成。然后它说可以评估一个列表。现在我有一些问题:

  1. 可以评估每个列表吗?每个列表都是表达式吗?
  2. 如果一个列表可以被计算,那么它的第一个元素可能是一个运算符,所以一个运算符是一个表达式?运算符是原子的还是其他的?
  3. 运算符car返回列表的第一个元素,如果可以计算列表,那么它将返回什么,运算符?你能给我一些例子来说明如何使用返回值吗?
  4. 运算符cdr将除第一个元素之外的元素作为列表返回,那么这个返回的列表不能被评估?

我是Lisp的新生,我不知道我是否清楚地解释了我的问题。

4

1 回答 1

2

Lisp S 表达式 (sexp) 要么是一个原子,要么是一个 sexps 列表。

1

所有的 Lisp 形式(即可以评估的东西)都是 sexps,但并非所有的 sexps 都是 Lisp 形式。

更具体地说,Lisp 形式是任何原子,或第一个元素是符号的列表。

(foo 42)       ; valid Lisp form
(undefined 42) ; Lisp form, but invalid because of undefined function
(42 foo)       ; not a Lisp form - numbers aren't symbols

2

正如我刚才提到的,list-that-is-a-Lisp-form 的“运算符”(第一个元素)必须是一个符号。(Lisp-1(例如 Scheme)允许在运算符位置使用任何 Lisp 形式,但Roots of Lisp讨论的是原始形式(Lisp-2)和 Common Lisp(Lisp-2);它们将运算符位置限制为符号.)

3

Lisp 代码在编译之前是 Lisp 数据。这很重要。

如果我说(car 'foo),程序会抱怨;没错,因为foo它不是一个列表。

如果我说(car '(car 'foo)),内部列表被评估(良好的旧引号语法'),并car提取操作符位置的东西 - 在这种情况下,符号car. 这在定义宏时很有用。

4

要看。

首先,假设我已经foo定义为两个参数的函数,并且bar定义为一个变量和一个参数的函数。还要记住,在后台,您的 Lisp 可能会调用eval您输入的任何内容。

现在(eval '(foo bar 42))是有效的,并且将foo使用参数 <the value of bar> 和42. (eval (cdr '(foo bar 42)))也是完全有效的;它等效于(eval '(bar 42)),它bar使用参数调用42

如果bar未定义为函数,cdr则第二个示例的 the 仍会生成有效的 Lisp 表单,但评估该表单将是错误的,因为(bar 42)调用了该函数bar(没有一个)。

谈论语法语义很有用。从语法上讲,任何原子,或任何在运算符位置带有符号的列表都是有效的。在语义上(在语法范围内),任何作为没有变量定义的符号的原子都是错误的;任何第一个元素是没有函数定义的符号的列表也是如此。

我希望这个答案可以帮助你。

于 2013-04-28T06:26:46.653 回答