Jis*_*Yoo 19 lisp scheme clojure common-lisp
一些文献说"以下形式的第一个子形式......"或"评估形式......",而其他一些文献说"评估表达......",大多数文献似乎都使用这两个术语.这两个术语是否可以互换?意义上有区别吗?
Rai*_*wig 21
摘要
说明
Common Lisp中形式和表达具有两种不同的含义和理解上的差异是有用的.
甲形式是一个正在运行的系统的Lisp内的实际数据对象.该表单是Lisp评估程序的有效输入.
EVAL将形式作为参数.
语法是:
eval form => result*
Run Code Online (Sandbox Code Playgroud)
EVAL没有以Lisp表达式的形式获得文本输入.它得到了形式.哪个是Lisp数据:数字,字符串,符号,程序作为列表,......
CL-USER 103 > (list '+ 1 2)
(+ 1 2)
Run Code Online (Sandbox Code Playgroud)
上面构造了一个Lisp形式:这里是一个列表,其中符号+作为第一个元素,数字1和2作为下一个元素.+命名一个函数,两个数字是参数.所以这是一个有效的函数调用.
CL-USER 104 > (eval (list '+ 1 2))
3
Run Code Online (Sandbox Code Playgroud)
上面给出了表格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
Run Code Online (Sandbox Code Playgroud)
使用示例:
CL-USER 105 > (defparameter foo 42)
FOO
CL-USER 106 > (eval 'foo)
42
Run Code Online (Sandbox Code Playgroud)
以下内容未创建有效表单:
'(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
Run Code Online (Sandbox Code Playgroud)
例:
CL-USER 107 > (eval '(1 + 2))
Error: Illegal argument in functor position: 1 in (1 + 2).
Run Code Online (Sandbox Code Playgroud)
然后,该表达式通常用于Lisp数据对象的文本版本 - 这不一定是代码.表达式由Lisp读取器读取并由Lisp打印机创建.
如果你在屏幕上或一张纸上看到Lisp数据,那么它就是一个表达式.
(1 + 2) ; is a valid expression in a text, `READ` can read it.
Run Code Online (Sandbox Code Playgroud)
dan*_*lei 10
这些术语的定义和用法因Lisp方言和社区而异,因此一般来说,对于Lisps的问题没有明确的答案.
有关它们在Common Lisp中的使用,请参阅Rainers详细解答.简要总结一下:
表单的HyperSpec条目:
形式 1.任何要评估的对象 2.符号,复合形式或自我评估对象.3.(对于操作员,如在
<<operator>> form'') a compound form having that operator as its first element.报价表中是一个常数形式.''
表达式的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根本没有提到形式,只讨论表达式.R6RS甚至给出了一个几乎听起来与上述完全相反的定义:
在纯粹的语法层面,两者都是形式,而形式是Scheme程序的句法部分的通用名称.
(谈论(define …)和之间的区别(* …).)
这绝不是一个科学的或基于标准的答案,但我根据我所听到的事情在我自己的脑海中建立的区别更多的是:表达是一种形式(或者可以be)在最终计划中进行评估.
例如,考虑一下表格(lambda (x) (+ x 1)).它是三个元素的列表:符号lambda,列表(x)和列表(+ x 1).所有这些元素都是形式,但只有最后一个是表达式,因为它"用于"评估; 前两个表单由macroexpander改组,但从未进行过评估.最外层的形式(lambda (x) (+ x 1))本身也是一种表达.
在我看来,这似乎是一个有趣的区别,但它确实意味着它是上下文敏感的:(x)始终是一种形式,并且可能会或可能不是取决于上下文的表达.