let
- 表单允许包含多个表达式:
(let ((x 4))
x
(+ x 1))
返回5
。
如何评估此表达式?
答案 0 :(得分:8)
它被称为隐式begin
,换句话说,您的代码被评估为好像它被编写:
(let ((x 4)) (begin x (+ x 1)))
答案 1 :(得分:4)
好吧,为了以防万一,让我们明白术语。 let
表单包含两部分:绑定和正文:
(let (<zero or more bindings>)
<one or more body expressions>)
绑定的格式为(<variable> <expression>)
,正文是一系列表达式。 let
的评估方式如下:
答案 2 :(得分:2)
您所描述的情况发生在Scheme的几个部分,而不仅仅是let
表达式。在下面......
let
表达式lambda
表达式中的参数列表之后(因此,在过程定义中的参数列表之后)cond
表达式 ...你可以写一个表达式列表。这些表达式隐含在begin
特殊形式中,评估顺序是从左到右,所有表达式依次计算,但返回的值是最后一个表达式。
例如,这个表达式:
(cond ((= 1 1) 1 2 3))
相当于:
(cond ((= 1 1) (begin 1 2 3)))
在这两种情况下,返回的值都是3
,因为这是列表中最后一个表达式的值。
答案 3 :(得分:1)
首先,术语 - 变量绑定后的表达式统称为正文,而正文中的每个表达式都是正文表达式。例如:
(let ((variable-1 value-1)
(variable-2 value-2))
body-expression-1
body-expression-2)
正文表达式包含在begin
中 - (let ((x 2)) x (+ x 1))
与(let ((x 2)) (begin x (+ x 1)))
相同。
评估begin
中的每个正文表达式,并将最终表达式的返回值用作整个正文的返回值。例如:(begin (+ x 1) (+ x 2))
将评估(+ x 1)
和(+ x 2)
,然后返回评估(+ x 2)
的结果。
如果begin
中的每个正文表达式都没有副作用,则可以删除除最后一个正文表达式之外的所有表达式,而不更改程序的运行时行为。这里唯一的例外是当其中一个初步正文表达式运行缓慢/没有返回/错误时 - 消除正文表达式消除了问题,这是对程序运行时行为的改变。
然而,当使用具有副作用的函数时,能够为其副作用调用一个或多个函数然后返回值是有用的。