我是Lisp的新手。我遇到了两个术语“列表”和“S表达式”。我只是无法区分它们。它们在Lisp中只是同义词吗?
我是Lisp的新手。我遇到了两个术语"列表"和"S表达式"。我不知道如何区分它们。它们在Lisp中是同义词吗?
我是Lisp的新手。我遇到了两个术语“列表”和“S表达式”。我只是无法区分它们。它们在Lisp中只是同义词吗?
我是Lisp的新手。我遇到了两个术语"列表"和"S表达式"。我不知道如何区分它们。它们在Lisp中是同义词吗?
首先,不是所有的S表达式都表示列表;例如表达式foobar
表示一个原子,也被认为是一个S表达式。当“cons”部分本身不是另一个列表(或nil)时,“cons cell”语法(car . cons)
也是一种S表达式。更常见的列表表达式,例如(a b c d)
,只是一系列嵌套的cons单元的语法糖;该示例展开为(a . (b . (c . (d . nil))))
。
其次,“S表达式”一词指的是语法 - (像这样的项(可能嵌套))
。这样的S表达式是Lisp源代码中列表的表示形式,但它本质上并不是一个列表。这种区别类似于十进制数字序列和它们的数值之间的区别,或者在引号内的字符序列和生成的字符串之间的区别。
这可能是一个过于技术化的区别;程序员经常像它们本身的价值一样引用值的文字表示。但是对于Lisp和列表,情况会变得有点棘手,因为Lisp程序中的每一件事情本质上都是一个列表。
例如,请考虑以下表达式:
(+ 1 2)
以上是一个简单的S表达式,表示一个扁平列表,由原子+
、1
和2
组成。
但是,在Lisp程序中,这样的列表将被解释为调用+
函数并以1和2作为参数。(请注意,被解释的是列表而不是S表达式;求值器接收到预先由阅读器解析的列表,而不是源代码文本。)
因此,虽然上述S表达式表示一个列表,但在Lisp程序的上下文中很少被称为“列表”。除非讨论宏或者阅读器的内部工作,或者因为其他生成代码或解析上下文而进行元语言讨论,否则典型的Lisp程序员通常会将上面的内容视为数字表达式。
另一方面,下列任何一个S表达式可能会被称为“列表”,因为将它们作为Lisp代码进行求值将产生由上面文字表示的列表作为运行时值:
'(+ 1 2)
(quote (+ 1 2))
(list '+ 1 2)
当然,代码和数据等价是 Lisp 的一大优点,因此区分是流动的。但我的观点是,虽然上述所有内容都是 S 表达式和列表,但只有一些在 Lisp 中的非正式说法中被称为“列表”。
eval
的参数。 - Will NessS-表达式是一种数据的符号表示法。
历史上,s-表达式(符号表达式的缩写)被描述为:
FOO
和BAR
(
expression-1 .
expression-2 )
NIL
(
A
.
(
B
.
NIL
)
)
简单地写成列表(A B)
还要注意的是,历史上程序文本的书写方式有所不同。下面是函数ASSOC
的示例。
assoc[x;y] =
eq[caar[y];x] -> cadar[y];
T -> assoc[x;cdr[y]]
{
,}
,class
,define
等)。顺便说一下:这使得可以直接表示 抽象语法树。再次强调:您编写的程序看起来就像语言的数据结构一样。eval
函数不操作字符串,这与大多数现代动态语言中同名函数不同。相反,它期望其参数已经是内存中代码的表达方式,即(一棵分层嵌套的)列表树。读取器将 S 表达式转换为要求求值的列表。因此,S 表达式是列表的文本表示形式。实际上,它们被序列化,就像 JSON 或 XML 可以表示对象树一样。 - Mark Reed(define S-expression?
(λ (object)
(or (atom? object) (list? object))))
;; Where atom? is:
(define atom?
(λ (object)
(and (not (pair? object)) (not (null? object)))))
;; And list? is:
(define list? (λ (object)
(let loop ((l1 object) (l2 object))
(if (pair? l1)
(let ((l1 (cdr l1)))
(cond ((eq? l1 l2) #f)
((pair? l1) (loop (cdr l1) (cdr l2)))
(else (null? l1))))
(null? l1)))))
两者的书写方式相似:(blah blah blah),可以嵌套。唯一的区别是列表以撇号为前缀。
在评估时:
如果需要,我们可以将列表转换为S表达式,反之亦然。
IAS: