有些文献说“以下形式的第一个子形式......”或“评估形式......”而其他一些文献说“评估表达......”,大多数文献似乎同时使用条款。这两个术语是否可以互换?意义上有区别吗?
答案 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)
始终是一种形式,可能会也可能不是一种表达,具体取决于上下文。