Lisp:list vs S-expression

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”指的是语法-(像这样的项目(可能是嵌套

我正在学习口齿不清。我遇到了两个术语“列表”和“S表达式”。我就是分不清他们。它们只是Lisp中的同义词吗?

首先,并非所有的S表达式都表示列表;表示裸原子的表达式(如
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)
  • 注释:
    ;这是一条评论
    | |这是一条评论|#
还有更多

列表

列表是一种数据结构。它由cons单元格和列表结束标记组成。列表在Lisp中有一个表示法,即s表达式中的列表。您可以对列表使用其他一些符号,但在Lisp中,我们已经确定使用s表达式语法来编写它们

旁注:程序和表格

在像Common Lisp这样的编程语言中,编程语言的表达式不是文本,而是数据!这与许多其他编程语言不同。编程语言Common Lisp中的表达式称为
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)))))