4.4 函数:对运算式语言的补充和组织
我们现在面临着一个新的词汇“运算式语言”(EL,Expression Language)。之所以需要强调它,是因为(目前)没有任何书籍将函数式语言的基础归结到这种运算范型中。
前面讲到,运算式语言的特点在于强调“求值运算”。我们也列举了JavaScript中的表达式运算符,看到这些运算符处理的运算元都是“值类型数据”。由此我们可以认为:JavaScript语言特性中的某个子集,可以作为一个最小化的运算式语言来使用——事实上我们也看到在Internet Explorer中将JavaScript的一个子集作为CSS的表达式(expression)来使用。
我们也讨论到,如果要在运算式语言中完成全部逻辑,那么它需要通过表达式或者运算来填补“被消灭掉的语句”。更确切地来说,它必须有能力实现“顺序、分支和循环”三种基本逻辑结构。在JavaScript中,可以通过“连续运算符(逗号)”和“三元条件表达式”来替代顺序和分支。因此,最后的问题是:如何在表达式级别实现循环?
我们也在前面给出了答案:使用函数递归来消灭循环语句。在这一个小节里,将进一步讨论这个话题。
4.4.1 函数是必要的补充
因为表达式运算是“求值运算”,所以有且仅有“当函数只存在值含义,且没有副作用”时,该函数才能作为表达式的运算元参与运算,并起到替代循环语句的作用。
显然,根据上面所述的“函数式语言中的函数”的特性,它确实可以充当这样的角色。因此,在一个纯粹的、完备的运算式语言中,函数是一个必要的补充。
但这只是理论上的、理想化的假设:如果“函数”是满足函数式语言的三个特性的话。而正如我们在前面所讨论的那样,JavaScript中的函数事实上仍然存在副作用。即使除去这个我们寄期望于“程序员的习惯”来解决的问题不谈,也还有一个无法回避的问题:JavaScript中的函数并不支持尾递归。





