OpenDSA 完整目录

Chapter 30 Interpreting the Functional Language SLang

| 关于   «  2. 基于环境的求值模型   ::   目录   ::   4. 定义 SLang 2  »

3. Let 表达式

3.1. Let 块

在 使用辅助函数编写 reverse 和 split 函数 中,我们引入了辅助函数,并考察了下面这个 split 函数。

var split = function (pivot,list) {
    if (fp.isNull(list)) {
        return [[],[]];
    } else {
        if (fp.isLT(fp.hd(list), pivot)) {
            return fp.makeList(
                fp.cons(fp.hd(list), fp.hd(split(pivot,fp.tl(list)))),        // Call split
                fp.hd(fp.tl(split(pivot,fp.tl(list))))                        // Call again
            );
        } else {
            return fp.makeList(
                fp.hd(split(pivot,fp.tl(list))),                              // Call split
                fp.cons(fp.hd(list), fp.hd(fp.tl(split(pivot,fp.tl(list)))))  // Call again
            );
        }
    }
};

虽然这样能正确工作,但它本质上效率低下,因为它总是对 split 进行两次递归调用,而这两次调用必然产生完全相同的结果。

更好的做法是缓存对 split 的一次调用结果,然后用这个缓存结果 代替那两次调用。如果我们能够声明一个局部于需要它的作用域的符号, 并把调用 split 的结果“赋”给该符号,就能在 SLang 1 中做到 这一点。这样一来,我们不必调用 split 两次,只需两次使用通过 与符号关联而缓存下来的结果。正是出于这一考虑,我们在 SLang 1 中 引入 let 块 。请看下面三个 let 块 的用法示例。在每个示例 中, let 之后对符号的赋值会在由关键字 in 和 end 括起来 的表达式中使用。

示例 1

let
   x = 1
   y = 2
in
   +(x,y)
end

示例 2

let
   x = 1
in
   let
      f = fn(y) => +(y,x)
   in
      let
          x = 2
      in
          (f 3)
      end
   end
end

示例 3

let
   x = 1
   sqr = fn (x) => *(x,x)
in
   let
      f = fn(y) => +(y,x)
   in
      let
          x = 2
      in
          +(x,(sqr (f x)))
      end
   end
end

有趣的是, let 块 (或称 let 表达式 )不过是 SLang 1 中某个 已有构造的 语法糖 。也就是说,当 SLang 1 解释器遇到 let 块 时,它可以在构建抽象语法树的过程中直接把它“翻译”成那个已有构造。 要想弄清这个已有结构是什么,请确定下面每句话中各个问号处应填 什么。

语句 1:当我们求值 let x = 1 y = 2 in <exp> end 时,我们返回 ??? 的值,其环境把 ??? 和 ??? 分别绑定到 ??? 和 ??? 。

语句 2:当我们求值 (fn (x,y) => <exp> 1 2) 时,我们返回 ??? 的值,其环境把 ??? 和 ??? 分别绑定到 ??? 和 ??? 。

通过做下面的练习题来检验你填写问号是否正确。

3.2. 作为语法糖的 Let 块

下面的随机化问题着重考察作为 语法糖 的 let 表达式 。连续三次 正确解答即可获得学分。

3.3. 嵌套 Let

下面的随机化问题着重考察嵌套 let 表达式 的求值。连续三次正确 解答即可获得学分。

提交答案时,请记住给出完整的指称值,例如 [ "Num", 0 ] ,而 不只是 0 。

3.4. 带闭包的嵌套 Let

下面的随机化问题着重考察带闭包的嵌套 let 表达式 的求值。连续 三次正确解答即可获得学分。

同样,提交答案时请记住给出完整的指称值。

   «  2. 基于环境的求值模型   ::   目录   ::   4. 定义 SLang 2  »

关闭窗口