如何评估 let-forms?

Posted

技术标签:

【中文标题】如何评估 let-forms?【英文标题】:How are let-forms evaluated? 【发布时间】:2012-03-13 03:43:21 【问题描述】:

let-forms 允许在内部包含多个表达式:

(let ((x 4))
   x
  (+ x 1))

返回5

如何评估这个表达式?

【问题讨论】:

【参考方案1】:

这称为隐式begin,换句话说,您的代码被评估为就好像它是编写的一样:

(let ((x 4)) (begin x (+ x 1)))

【讨论】:

groups.csail.mit.edu/mac/ftpdir/scheme-7.5/7.5.17/doc-html/…【参考方案2】:

好吧,让我们弄清楚术语以防万一。 let 表单有两部分:bindingsbody:

(let (<zero or more bindings>)
  <one or more body expressions>)

绑定的形式为(&lt;variable&gt; &lt;expression&gt;),主体是一系列表达式。 let 的评估方式如下:

创建一个本地环境,其中每个变量都绑定到相应绑定中表达式的计算结果。 按顺序计算正文中的表达式。 结果:正文中最后一个表达式的结果。

【讨论】:

【参考方案3】:

您所描述的情况出现在 Scheme 的多个部分中,而不仅仅是在 let 表达式中。接下来...

let 表达式中的变量绑定列表之后 在lambda 表达式中的参数列表之后(因此,在过程定义中的参数列表之后) cond 表达式中的每个子句之后

...你可以写一个表达式列表。这些表达式隐式包含在begin 特殊形式中,计算顺序是从左到右,依次计算所有表达式,但返回值是最后一个表达式的值。

例如,这个表达式:

(cond ((= 1 1) 1 2 3))

相当于:

(cond ((= 1 1) (begin 1 2 3)))

在这两种情况下,返回值都是3,因为这是列表中最后一个表达式的值。

【讨论】:

【参考方案4】:

首先,术语——变量绑定之后的表达式统称为body,body中的每一个表达式都是一个body表达式。例如:

(let ((variable-1 value-1)
      (variable-2 value-2))
  body-expression-1
  body-expression-2)

body 表达式用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 中的每个主体表达式都没有副作用,则可以删除除最后一个主体表达式之外的所有主体表达式,而不会改变程序的运行时行为。这里唯一的例外是当一个初步的主体表达式运行缓慢/不返回/出错时——消除主体表达式消除了问题,这是对程序运行时行为的改变。

但是,当使用具有副作用的函数时,调用一个或多个函数以获取其副作用然后返回值的能力很有用。

【讨论】:

以上是关于如何评估 let-forms?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用函数重新评估 Python 中先前评估的变量?

如何评估假设检验的好坏

如何评估雪花存储过程中的语句

如何评估树枝表情

如何避免短路评估

作为参数传递时如何评估函数