这是这个系列的最后一篇,从编程范型的角度概览,前面几篇的链接在文章后半部分有汇总。
我在之前已经介绍过编程范型的概念,而事实上,我们到现在为止,纠结在这四门迥异的语言上面,浅看是各种语言特性,深看就是编程范型和思维方法。
下面这张 “神图” 来自于这里,可以说是对于范型和语言归类的概览,从左往右从更强的声明式向着更弱的声明式发展;依据状态分为 Unnamed state(串行或并发,包含逻辑式和函数式这几种分类)、Nondet. state(所谓的不确定性状态)和 Named state(包含数据流、消息传递和状态共享这几种分类),Haskell 出现在了左侧函数式语言的分支内,而 Java 出现在了右侧状态共享的分支内。有了这棵大树,范型之间的关系变得很容易识别,比如这样的粗线条:
最初的范型仅仅是简单的 “record” 而已,纯粹的声明和静态的描述;有一天加上了过程,于是有了一阶函数式编程;之后有一天再加上了状态,于是有了命令式编程。
一阶函数式编程加上闭包,得到了真正的函数式编程(有了闭包,就可以写高阶函数了);命令式编程加上对函数的搜索,就得到了串行的 OO 以及状态共享的函数式编程。
……
从维基百科的 Comparison of multi-paradigm programming languages 词条中,可以看得到常见多范型语言的分类情况。Java 和 JavaScript 位列其中,从表中的分别可以看出二者的分别:因为 Java 有线程的概念,可以写并发编程范型的代码;有泛型的定义,可以进行泛型编程;有专门的 Class 类,可以反射和自省。
这里提到 “多范型”,其实这个概念定义也不精确,大致来说,除了 Haskell,我们今天讨论的三门其它的语言,都算是多范型的编程语言。例如用 Java 也可以写函数式编程的代码,但是需要避免使用状态。越是强大的语言,约束越少,可能性越强,代码却不一定简洁。
因此与其讨论一门语言 “可以” 写哪些范型,倒不如讨论一门语言 “擅长” 写哪些范型:
- Java,经典的结构化和指令式编程语言。擅长表现面向对象的范型,限制也很多,不容易搞破坏,但是讽刺的是,它本身却存在非对象的原语类型,就是 int、float、double 等等这些东西,这个不足在 Groovy 中被修复。
- JavaScript 也擅长表现面向对象的范型,但是它是基于原型的面向对象,而非基于类的面向对象。它的约束很少,语法的坑很多。有了闭包以后,再加上 JavaScript 本身是单线程的,没有线程这样的概念,就没有同步、并发、锁等等引发复杂性的概念,没有任何东西可以阻塞当前程序的运行(没有 sleep 也没有 wait),于是事件驱动的编程范型就可以大行其道了。
- Groovy 包含 Java 一切包含的东西,但是由于语言灵活,特别是动态语言的特性,在很多范型编程上面更有优势,比如面向切面编程。之前介绍过的元编程,在 Groovy 里发扬光大。Groovy 的脚本友好特性,使得它很容易实现简洁的 DSL 用于配置描述。
- Haskell 就是专注于函数式编程的典型。之前已经介绍过函数式编程的诸多特性,而且它具备良好的模块化特性。它本身可以称为真正的 “non-strict programming language”,换言之,function 的参数可以不被计算出来,真正实现无限集合的 lazy 计算。
纵览编程范型之后,再来回顾一下之前几篇的内容,欢迎移步阅读:
- 《从 Java 和 JavaScript 来学习 Haskell 和 Groovy(引子)》,记载了写这一系列文字的初衷,以及为什么选这几门语言。
- 《从 Java 和 JavaScript 来学习 Haskell 和 Groovy(类型系统)》,介绍了从类型角度看编程语言的几个重要概念,比如动态/静态类型,类型推导,强/弱类型,结构类型和鸭子类型;介绍了这几种语言类型系统的基础;还有几个对结构描述的基础概念,包括函数、类、接口和型别。
- 《从 Java 和 JavaScript 来学习 Haskell 和 Groovy(元编程)》,介绍了这四种语言实现元编程方面的能力和特性,包括 Java 的自省,编译期织入和运行期代理,Haskell 的模板,JavaScript 的两条元编程基本归纳,以及 Groovy 的丰富元编程特性,比如 MethodMissing,GroovyInterceptable,Categories 和 Magic Package。
- 《从 Java 和 JavaScript 来学习 Haskell 和 Groovy(DSL)》,介绍了这几门语言对于 DSL 实现的常见模式和语法糖,比如 Java 的链式调用和泛型传递,闭包和 Lambda 表达式,JavaScript 的高阶函数,Groovy 对于 DSL 友好的语法糖,Haskell 的模式匹配和 List Comprehension,尾递归和惰性求值等等。
如上仅仅只是冰山一角,希望对于想了解这四门语言和相关编程范型的读者有帮助,也是对我自己而言,通过 Java 和 JavaScript 来学习 Groovy 和 Haskell 的一个总结。很多特性都没有涉及,比如 Haskell 的很多高级特性,是因为我觉得我没法写好,就先不写了。
工作需要,要开始学习 Scala 了,我本来对 Scala 的认识水平仅仅停留在 “了解” 的基础之上,通过最近这段时间的学习,我发现有了 Groovy 和 Haskell 的基础以后,再来看 Scala 的那些语法和特性,阅读的速度很快,很多面孔都似曾相识。
文章未经特殊标明皆为本人原创,未经许可不得用于任何商业用途,转载请保持完整性并注明来源链接 《四火的唠叨》
groovy 中动态类型还是比较坑的