现在的位置: 首页 > 综合 > 正文

西行漫记(7):再论语法糖

2013年03月29日 ⁄ 综合 ⁄ 共 965字 ⁄ 字号 评论关闭
前一个blog里,我这样写道:“今天的object bootcamp再度证明,一切反动派都是纸老虎……嗯,一切面向对象都是语法糖。”读者dongbin提出了一个很有趣的问题:

“一切面向对象都是语法糖”是否意味着所有面向对象编程语言都可以形式化的转换为函数式编程语言呢?比如LISP。那么可否通过直接在LISP之上添加语法糖来得到更简洁,强大的语言呢?

首先,确实可以“直接在LISP之上添加语法糖”,在SICP第三章(还是第四章?)就做了这样的事情。这个exercise的效果是,你可以直观地看到:所谓“面向过程”和“面向对象”,其实就是同样的一组lambda,用不同的语法糖表现出来而已,背后是完全一样的事情。这并不是说语法糖不重要,而是说你可以(并且应该)根据不同的情况选择最方便的语法糖,而不是让某一种语法糖(譬如“面向对象设计原则”)绑住手脚。

但另一个问题是,并非“所有面向对象编程语言都可以形式化的转换为函数式编程语言”。问题的根源是丘奇代数(Church Calculus)理论:一切可有效计算的函数(包括定值函数)都可以归约为lambda运算。但含有内部状态的函数不是一个可有效计算的函数,因为在不同时间它给出的值不同。所以,在有内部状态存在的情况下,面向对象程序通常是不能用(严格的)函数式语言描述的。(但赋值操作并不等价于内部状态。有赋值操作的程序很多时候也可以归约为函数,在《重构》书中有很多这样的例子。)

更加有趣的问题接踵而来:对于一个web应用而言,很多时候我们可以有效地将其可变状态限制在首尾两端。也就是说,web层是有状态的(当前用户session),其他的状态都持久化地保存在数据库里,而web应用本身——或者至少是“业务逻辑”的部分——很多时候可以是完全无状态的,也就是说可以将其归约为函数。这样做的好处不仅仅是优雅。函数是不存在并发问题的,因此无状态的web应用可以最方便地实现web-farm的集群部署,从而获得线性的scalability。

另一个有趣的现象是Java5引入的静态导入(static import)特性。以前经常说“static helpers are evil”,但static import引入的只能是static helper。从某种意义上,静态导入正是面向对象借鉴函数式编程走出的一步。

抱歉!评论已关闭.