研讨-计算机科学基础

    Programming Language

研讨 1:

function f(x) { return x*2; } 是一个语句(statement),而 (x) => { return x*2; } 却是一个表达式(expression)。为什么?

我:这个时代的计算机会对表达式求值,于是可以认为表达式是有返回值的,进而通过是否有返回值来判断一个(串)符号,对计算机来说是否是表达式语句只是声明一件事情,通常没有返回值(计算机一般会对语句的输入返回 undefined 字样,以表示没有返回值)。

function f(x) { return x*2; } 没有返回值,且它的意思是定义(创造)一个函数,所以它是语句(x) => { return x*2; } 的返回值是 (x) => { return x*2; } ,所以从返回值的角度它是个典型的表达式

老师:“回复 undefined 的都是语句,undefined 的意思是‘没有值’。function f(x) { return x*2; }等价于赋值语句。它创造了一个新的变量f,但这个动作本身没有值。被创造的变量f却是一个表达式,它有值。要区分‘创造变量的动作”和“变量本身’。”

老师:“打个比方,‘鞋子’是有值的表达式,‘把鞋放进盒子里’却没有值,它是一个动作。”

注释1:尽管类似Haskell的语言还能看到Lazy evaluation这样的惰性求值设计,不过老师提到人类在走了很多弯路、踩了很多坑之后总结出的设计结论是:要先对表达式求值,之后再进行下一步计算或者传递。应当认为“活性求值”(eager evaluation)比惰性求值(lazy evaluation)更科学。

注释2:有些语言的语句(statement)也有返回值。比如在Scheme语言中,语句的返回值就是 void 。之所以这样,是因为 Scheme 的设计者希望该语言中不需要区分表达式和语句,这样整个语言的语法结构就非常简洁优雅,其解释器相比其他语言的解释器会少处理很多不必要的东西。

注释3:从字符上看虽然表达式 (x) => { return x*2; } 的返回值是它本身,其实不应简单认为是它本身。真实情况是我们输入了 (x) => { return x*2; } 这一字符串(a pattern of rules),然后计算机对该字符串求值(解释),就得出这个值是一个函数,于是计算机返回这个值,即这个函数。然后这个函数的输出形式被设计成相同的字符串。就好像我们输入数字 3 ,计算机返回数字 3 ,这两个 3 不是同样的 3 ,前者是以字符形式输入的表达式,后者是值(计算机对输入解释后的结果)。老师给的一个形象的例子是,我们输入的是榨汁机的图纸,计算机给我们的是一个真正的榨汁机(求值的结果)。区别这两者会对今后的思维模型有重要的作用。

注释4:该思考题中讨论的代码用的是 Javascript 语言。


打赏