面向过程虽然穿着函数这件马甲,与函数式编程应还是不一样的。在面向过程中,我们总是先定义变量,而后写过程,也就是说是围绕“事物”展开思考,尽管变量表示事物,可能缺失了事物本身应具有的丰富内涵。
函数式语言有什么优秀的特性,是面向对象所缺失的呢?lambda表达式、closure机制、callback机制还是什么呢?在面向类的语言中,这些特性有相应的实现方式。lambda表达式可以通过匿名类进行模拟,closure机制与类本身就心有灵犀,颇为相似(在Javascript可以通过闭包模拟类,但存在内存泄露问题),callback机制在“策略”、“观察者”“命令”等模式都有所体现。(从这个角度看,模式有时候可以看作超越本土语言限制从而具有另一种语言能力的一个途径。Peter Noving 有篇文章《Design Patterns in Dynamic Programming》展示了在一些动态语言中天生具有GoF23种模式其中16种模式的能力。)
在围绕“事物”的编程范式中,有面向变量(如C)、基于类的面向对象(如Java、C#,C++混合面向变量和基于类的面向对象的两种能力),基于原型的面向对象(如Javascript,当然Javascript不止具备这一能力 )、面向进程的(如Erlang),对"事物"不同粒度和方式的抽象,都有其合适的应用场景,在某些场景用变量思考方便一些、在某些场景用类思考方便一些、在某些场景用对象思考方便一些、在某些场景则用进程思考方便一些。
从直观上看,目前我的认识,语言对事物的抽象或仿生应该具备三种能力:1)事物可以同时具有状态和行为,这点Java、C#等做得不错,只是类是一个相对静止的概念,也丢失了事物的一些内涵;2)事物可以自我成长,可以有新的记忆和习惯或放弃旧的记忆和习惯,也就说事物可以动态增删状态和行为,这点Javascript似乎具备了;3)事物可以自我独立运行,也就说事物应该具备进程的特性,“万物并育而不相害,道并行而不相悖”,这点Erlang做得不错,Erlang支持并行、分布、容错、热升级等特性,“无锁”的特点更容易将多核、分布计算的能力发挥得淋漓尽致。
Anders Hejlsberg预测语言的发展趋势是:声明式、动态式和并发式。Anders作为语言设计者,应有更深入的思考。而我(们)作为语言使用者,只能根据一些常识进行思考。但思考的结果似乎有些相似之处:动态式表达了事物自我成长的特性;并行式是表达了事物自我运行的特性。
至于声明式,一般将函数式语言归入声明式范式。之前的讨论改变我用声明式表达世界观的做法,现在我认为声明实际只是对方法论的一种描述,描述一种隐藏how的能力。从这个角度,语言的发展就是一个不断声明化的过程。汇编语言(徒步)相对于机器语言(爬走)是一种声明式表达,面向变量(自行车)相对汇编语言是一种声明式表达,面向对象(汽车)相对于面向变量是一种声明式表达。语言的发展好象交通工具的发展一般,总是希望可以使我们更快地到达目的地。
未来语言将在对“事物”更完善的抽象基础之上,即引入“动态式与并行式”;用更“声明式”的方式表达事物之间的“相互作用”。
此外语言的抽象程度,应与人的当下认知协相调,倘若语言的抽象并没有控制或降低解决问题的复杂度,则可能成为程序员的“心智负担”,反而制约了我们解决问题的能力。
未来还可能出现“元语言”,领域专家可按专业知识,使用“元语言”生成一种贴近领域术语与概念的语言。领域专家与程序员的关系就可能变得疏远,因为其可以直接使用生成后的语言对领域进行建模并实现。而程序员将再次被进行大的分化,一部分回到程序技术本身,一部分则跳到领域中去。上一次大的分化,是软硬技术的分离,这一次分化,将是领域与(程序)技术的分离。
[该贴被jdon007于2010-11-11 22:57修改过]