OpenDSA 完整目录

Chapter 30 Interpreting the Functional Language SLang

| 关于   «  3. Let 表达式   ::   目录   ::   5. 打结  »

4. 定义 SLang 2

4.1. SLang 2:一种命令式语言

现在,我们将向这门简单语言加入一些超出纯函数式编程范畴的特性。

在这个新版本的 SLang 中,即 SLang 2 (Simple Language version 2),标准算术运算符和布尔运算符现在采用中缀形式,这只是具体语法 上的一点小改动。更重要的是,我们新增了 if-then-else 表达式, 以及赋值语句、打印语句,还有 let 块内语句的顺序执行。这最后三项 新增内容(即语句的新增,而非表达式的新增)合在一起,把我们的简单 语言变成了一种 命令式语言 ,也就是说,程序员依靠改变变量状态 (即副作用)来计算所需的值。

向 SLang 添加赋值语句

语法:

<exp>        ::= <var_exp> | ... | <assign_exp>
...
<assign_exp> ::= set <var_exp> = <exp>

语义:

  • 求值等号右侧的表达式(即 RHS 表达式)。

  • 把所得的值赋给左侧的变量(即 LHS)。

  • 返回 RHS 表达式的值。

表达式在求值时返回值。语句在求值时产生副作用。

赋值语句实际上是一种 表达式语句 ,因为它既是表达式(因为它 返回一个值),又是语句(因为它有副作用)。

向 SLang 添加打印语句

语法:

<exp>       ::= <var_exp> | ... | <print_exp>
...
<print_exp> ::= print <exp>

语义:

  • 求值该表达式。

  • 把所得的值发送到控制台。

  • 不返回任何值(即 JavaScript 中的 ‘undefined’)。

这是一种 纯语句 ,即没有返回值的语句。

向 SLang 的 let 块添加顺序执行

语法:

<exp>      ::= <var_exp> | ... | <let_exp>
<let_exp>  ::= let <bindings> in <block> end
...
<block>    ::= <exp> ( ; <exp> )*

注意,分号是表达式分隔符,而不是终止符。

块的语义:

  • 按顺序求值块中的表达式。

  • 返回最后一个表达式的值。

为了让顺序执行有用,块中的所有表达式(最后一个除外)必须是 什么?

示例: 利用上面关于赋值、打印和顺序执行的语义定义,说服自己 相信下面的示例程序会产生右侧所示的输出。做完之后,再通过尝试 这个随机化问题来获得更多练习。

let                                                  Output:
     x = 1
     y = 2
     sqr = fn (x) => (x * x)
in                                                   ["Num",6]
    let                                              ["Num",2]
        f = fn (x) => (y * x)                        ["Num",64]
        g = fn () => set y = add1(y)                 ["Num",10]
        h = fn () => set x = add1(x)                 ["Num",6]
        x = 3                                        ["Num",15]
    in                                               ["Num",50]
        set x = (2 * x);
        print x;    print y;
        print (sqr (x + y));
        print (f 5);
        (g);
        (h);
        print x;
        print (f 5);
        set y = 10;
        print (f 5)
    end
end

4.2. SLang 2 程序的输出

下面的问题将帮助你掌握 SLang 2 的语法和语义。要获得这道题的学分, 你必须连续三次正确完成这个随机化问题。

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

   «  3. Let 表达式   ::   目录   ::   5. 打结  »

关闭窗口