Lisp表单和Lisp表达式是一样的吗?

时间:2013-06-20 06:26:45

标签: clojure lisp scheme common-lisp

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

3 个答案:

答案 0 :(得分:21)

<强>摘要

form是Lisp代码作为数据。 expression是数据作为文本。

<强>解释

在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

Above将表单赋予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.

答案 1 :(得分:10)

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

对于它们在Common Lisp中的使用,请参阅Rainers详细解答。简要总结一下:

form的HyperSpec条目:

  

表格1.任何要评估的对象一个符号,一个化合物   形式或自我评估的对象。 3.(对于运营商,如同   <<operator>> form'') a compound form having that operator as its first element.报价表格是一种不变的形式。“

expression的HyperSpec条目:

  

表达式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根本没有提及 form ,只讨论表达式。 R6RS甚至给出了一个几乎与上述完全相反的定义:

  

在纯粹的句法层面,两者都是形式,形式是   Scheme程序的语法部分的通用名称。

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

答案 2 :(得分:6)

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

例如,考虑形式(lambda (x) (+ x 1))。它是三个元素的列表:符号lambda,列表(x)和列表(+ x 1)。所有这些元素都是形式,但只有最后一个是表达式,因为它“用于”评估;前两个表单由macroexpander改组,但从未进行过评估。最外面的形式(lambda (x) (+ x 1))本身也是一个表达式。

在我看来这是一个有趣的区别,但它确实意味着它是上下文敏感的:(x)始终是一种形式,可能会也可能不是一种表达,具体取决于上下文。