let-forms 如何评估?
let
- 表单中允许包含多个表达式:
(let ((x 4))
x
(+ x 1))
返回5
。
这个表达式是如何计算的?
let
-forms are allowed to contain several expressions inside:
(let ((x 4))
x
(+ x 1))
returns 5
.
How is this expression evaluated?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这称为隐式
begin
,换句话说,您的代码将被评估,就好像它是这样编写的:that's called an implicit
begin
, in other words your code is evaluated as if it was written:好吧,为了以防万一,让我们弄清楚术语。
let
形式有两部分:绑定 和 主体:绑定的形式为
(; )
,主体是表达式序列。let
的计算方式如下:Well, let's get the terminology clear just in case. A
let
form has two parts: bindings and a body:A binding has the form
(<variable> <expression>)
, and the body is a sequence of expressions. Alet
is evaluated like this:您所描述的情况发生在Scheme 的多个部分中,而不仅仅是在
let
表达式中。在下面的内容中...let
表达式中的变量绑定列表之后lambda
表达式中的参数列表之后(因此,在 a 中的参数列表之后)过程定义)cond
表达式中的每个子句之后...您可以编写一个表达式列表。这些表达式隐式地包含在
begin
特殊形式中,求值顺序是从左到右,所有表达式依次求值,但返回的值是最后一个表达式的值。例如,此表达式:
等效于:
在这两种情况下,返回值为
3
,因为这是列表中最后一个表达式的值。The situation you're describing occurs in several parts in Scheme, not only in a
let
expression. In the following ...let
expressionlambda
expression (and consequently, after the list of parameters in a procedure definition)cond
expression... you can write a list of expressions. Implicitly those expressions are enclosed inside a
begin
special form, the order of evaluation is from left to right, all the expressions are evaluated in turn but the value returned is that of the last expression.For example, this expression:
Is equivalent to:
In both cases, the returned value is
3
, because that's the value of the last expression in the list.首先,术语——变量绑定之后的表达式统称为主体,主体中的每个表达式都是一个主体表达式。例如:
主体表达式包含在
begin
中 --(let ((x 2)) x (+ x 1))
与(let ( (x 2))(开始x (+ x 1)))
。begin
中的每个主体表达式都会被求值,最终表达式的返回值将用作整个主体的返回值。例如:(begin (+ x 1) (+ x 2))
将评估(+ x 1)
和(+ x 2)
和然后返回计算(+ x 2)
的结果。如果
begin
中的每个主体表达式都没有副作用,则可以删除除最后一个主体表达式之外的所有主体表达式,而不会更改程序的运行时行为。这里唯一的例外是当初步主体表达式之一运行缓慢/不返回/出错时——消除主体表达式可以消除问题,这是对程序运行时行为的更改。但是,当使用具有副作用的函数时,调用一个或多个函数以消除其副作用,然后返回一个值的功能非常有用。
First, terminology -- the expressions after the variable bindings are collectively known as the body, and each expression in the body is a body expression. Ex:
The body expressions are wrapped in
begin
--(let ((x 2)) x (+ x 1))
is the same as(let ((x 2)) (begin x (+ x 1)))
.Each body expression in
begin
is evaluated and the return value of the final expression is used as the return value for the entire body. Ex:(begin (+ x 1) (+ x 2))
will evaluate(+ x 1)
and(+ x 2)
and then return the result of evaluating(+ x 2)
.If every body expression in
begin
has no side effects, then all but the last body expression can be removed with no change to the runtime behavior of the program. The only exceptions here are when one of the preliminary body expressions runs slowly/doesn't return/errors out -- eliminating the body expression eliminates the problem, which is a change to the runtime behavior of the program.However, when using functions with side effects, the ability to call one or more functions for their side effects and then return a value is useful.