Lisp:list vs S-expression
我正在学习口齿不清。我遇到了两个术语“列表”和“S表达式”。我就是分不清他们。它们只是Lisp中的同义词吗?首先,并非所有的S表达式都表示列表;表示裸原子的表达式(如Lisp:list vs S-expression,list,lisp,s-expression,List,Lisp,S Expression,我正在学习口齿不清。我遇到了两个术语“列表”和“S表达式”。我就是分不清他们。它们只是Lisp中的同义词吗?首先,并非所有的S表达式都表示列表;表示裸原子的表达式(如foobar)也被视为S表达式。与“cons单元格”语法一样,当“cons”部分本身不是另一个列表(或nil)时使用(car.cons)。更常见的列表表达式,如(abcdd),只是嵌套cons单元格链的语法糖;该示例扩展为(a.(b.(c.(d.nil)) 其次,术语“S-expression”指的是语法-(像这样的项目(可能是嵌套
foobar
)也被视为S表达式。与“cons单元格”语法一样,当“cons”部分本身不是另一个列表(或nil)时使用(car.cons)
。更常见的列表表达式,如(abcdd)
,只是嵌套cons单元格链的语法糖;该示例扩展为(a.(b.(c.(d.nil))
其次,术语“S-expression”指的是语法-(像这样的项目(可能是嵌套的))
。这样的S表达式是Lisp源代码中列表的表示形式,但从技术上讲,它本身并不是一个列表。这种区别与十进制数字序列与其数值之间的区别相同,或者引号内的字符序列与结果字符串之间的区别相同
这也许是一种过于技术性的区别;程序员通常引用值的文字表示,就好像它们本身就是值一样。但是对于Lisp和list,事情会变得有点棘手,因为Lisp程序中的所有内容在技术上都是一个list
例如,考虑这个表达式:
(+12)
上面是一个简单的S表达式,它表示一个平面列表,由原子+
、1
和2
组成
但是,在Lisp程序中,这样的列表将被解释为对+
函数的调用,其中1和2作为参数。(请注意,这样解释的是列表,而不是S表达式;计算器得到的是已由读取器预解析的列表,而不是源代码文本。)
因此,尽管上面的S表达式表示一个列表,但在Lisp程序的上下文中,它很少被称为“列表”。除非讨论宏或读取器的内部工作,或者因为其他代码生成或解析上下文而参与元语法讨论,否则典型的Lisp程序员会将上述内容视为数值表达式
另一方面,以下任何S表达式都可能被称为“列表”,因为将它们作为Lisp代码进行计算将生成由上述文字S表达式表示的列表作为运行时值:
'(+ 1 2)
(quote (+ 1 2))
(list '+ 1 2)
当然,代码和数据的等价性是Lisp最酷的地方之一,所以区别是不固定的。但我的观点是,虽然上面所有的都是S表达式和列表,但在随意的Lisp语言中,只有一些会被称为“列表”。您应该首先了解Lisp的主要功能-程序可以作为数据进行操作。与其他语言(如C或Java)不同,在其他语言中,您使用特殊语法(
{
,}
,类
,定义
,等等)编写程序,在Lisp中,您将代码编写为(嵌套的)列表(顺便说一句,这允许直接表示)。再一次:您编写的程序看起来就像语言的数据结构
当你谈论它作为数据时,你称它为“列表”,但是当你谈论程序代码时,你最好使用术语“s-expression”。因此,它们在技术上是相似的,但在不同的环境中使用。这些术语混合在一起的唯一真实的地方是元编程(通常是宏)
还要注意的是,s表达式也可能只包含原子(如数字、字符串等) S表达式是数据的符号。 历史上,s表达式(符号表达式的缩写)被描述为:
- 像
和FOO
BAR
- 将s表达式作为其第一个和第二个元素的cons单元格:
expression-1(
expression-2)
- 列表终止符号
NIL
- 还有一个编写列表的惯例:
(
(
B
)
编写起来更简单,因为列表)
(a B)
ASSOC
的示例
assoc[x;y] =
eq[caar[y];x] -> cadar[y];
T -> assoc[x;cdr[y]]
历史上也存在从这些m表达式(元表达式的缩写)到s表达式的映射。如今,大多数Lisp程序代码都是使用s表达式编写的
这里描述了这一点:
在像Common Lisp这样的Lisp编程语言中,现在s表达式有更多的语法,可以编码更多的数据类型:
- 符号:
,symbol123
|这是一个带空格的符号|
- 编号:
,123
,1.0
1/3
- 字符串:
“这是一个字符串”
- 字符:
,\a
\space
- 向量:
#(a b c)
- 费用和清单:
,(a.b)
(a.b.c)
- 注释:
,;这是一条评论
| |这是一条评论|#
Lisp表单
例如,函数调用是Lisp数据,其中该调用是一个列表,其中函数符号作为其第一个元素,ne
(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)))))