20

一些文献说“以下形式的第一个子形式......”或“评估一个形式......”而其他一些文献说“评估一个表达式......”,大多数文献似乎都使用这两个术语。这两个术语可以互换吗?意思有区别吗?

4

3 回答 3

24

概括

表单是作为数据的Lisp 代码。表达式是文本形式的数据。

请参阅 Common Lisp 标准中的词汇表条目:

解释

在 Common Lisp中,形式表达有两种不同的含义,理解它们的区别很有用。

表单是运行中的 Lisp 系统中的实际数据对象。该表单是 Lisp 评估器的有效输入。

EVAL采用形式作为参数。

语法是:

eval form => result*

EVAL不会以 Lisp 表达式的形式获得文本输入。它得到表格。这是 Lisp 数据:数字、字符串、符号、程序作为列表,......

CL-USER 103 > (list '+ 1 2)
(+ 1 2)

上面构造了一个 Lisp 形式:这里是一个列表,其中符号+作为第一个元素,数字 1 和 2 作为下一个元素。+命名一个函数,两个数字是参数。所以这是一个有效的函数调用。

CL-USER 104 > (eval (list '+ 1 2))
3

上面将表单(+ 1 2)作为数据对象提供给EVAL并计算结果。我们不能直接看到表单——我们可以让 Lisp 系统为我们创建打印的表示。

表单实际上是一个作为数据对象的 Lisp 表达式。

这有点不寻常,因为大多数编程语言都是通过描述文本输入来定义的。Common Lisp 描述数据输入到EVAL. 表单作为数据结构。

以下在评估时创建一个 Lisp 表单:

"foo"         ; strings evaluate to themselves

'foo          ; that evaluates to a symbol, which then denotes a variable

123

(list '+ 1 2) ; evaluates to a list, which describes a function call

'(+ 1 2)      ; evaluates to a list, which describes a function call

示例使用:

CL-USER 105 > (defparameter foo 42)
FOO

CL-USER 106 > (eval 'foo)
42

以下内容创建有效表单:

'(1 + 2)            ; Lisp expects prefix form

(list 1 '+ 2)       ; Lisp expects prefix form

'(defun foo 1 2)'   ; Lisp expects a parameter list as third element

例子:

CL-USER 107 > (eval '(1 + 2))

Error: Illegal argument in functor position: 1 in (1 + 2).

然后,该表达式通常用于 Lisp 数据对象的文本版本——不一定是代码。表达式由 Lisp 阅读器读取并由 Lisp 打印机创建。

如果你在屏幕或一张纸上看到 Lisp 数据,那么它就是一个表达式。

(1 + 2)             ; is a valid expression in a text, `READ` can read it.
于 2013-06-20T07:58:28.550 回答
11

这些术语的定义和使用因 Lisp 方言和社区而异,因此对于 Lisp 的一般问题没有明确的答案。

有关它们在 Common Lisp 中的使用,请参阅 Rainers 详细答案。做一个简短的总结:

表单的 HyperSpec 条目:

表格 n. 1. 任何要被评估的对象。2. 一个符号、一个复合形式或一个自我评价的对象。3.(对于运算符,如 <<operator>> form'') a compound form having that operator as its first element.引号形式是常量形式。''

表达式的 HyperSpec 条目:

表达式 n. 1. 对象,常用于强调使用对象以特定格式编码或表示信息,例如程序文本。The second expression in a let form is a list of bindings.'' 2. the textual notation used to notate an object in a source file.表达式“样本等同于(引用样本)。”

因此,根据 HyperSpec,表达式用于(文本)表示,而形式用于被评估的 Lisp对象。但是,正如我上面所说,这只是 HyperSpec(以及 Common Lisp)上下文中这些术语的定义。

然而,在 Scheme 中,R5RS 根本没有提到形式,只谈论表达式。R6RS 甚至给出了一个几乎与上述完全相反的定义:

在纯句法层面,两者都是形式,形式是 Scheme 程序句法部分的总称。

(谈论(define …)和之间的区别(* …)。)

于 2013-06-20T07:23:38.197 回答
6

这绝不是一个科学或基于标准的答案,但我根据我所听到的事情在我自己的脑海中建立的区别更像是:表达式是一种形式,它将是(或可以be) 在最终程序中进行评估。

因此,例如,考虑表单(lambda (x) (+ x 1))。它是一个包含三个元素的列表:符号lambda、列表(x)和列表(+ x 1)。所有这些元素都是形式,但只有最后一个是表达式,因为它“旨在”用于评估;前两种形式被宏扩展器洗牌,但从未评估过。最外层的形式(lambda (x) (+ x 1))本身也是一个表达式。

在我看来,这似乎是一个有趣的区别,但它确实意味着它是上下文相关的:(x)始终是一种形式,并且可能是也可能不是取决于上下文的表达式。

于 2013-06-20T20:18:40.627 回答