说起编程范式我们应知道什么

1,146 阅读5分钟

本文讲了关于范式相关的一些基础理论。

我们会对相关概念做一下介绍,然后讨论几种具体的范式。


1 概念

讨论这个话题前先熟悉几个概念,

1.1 范式

范式的词源

Paradigm comes from Greek παράδειγμα (paradeigma), "pattern, example, sample"[1] from the verb παραδείκνυμι (paradeiknumi), "exhibit, represent, expose"[2] and that from παρά (para), "beside, beyond"[3] and δείκνυμι (deiknumi), "to show, to point out"

结合另一个常用的单词组合Scientific paradigm 理解,科学历史学家 Thomas Kuhn 将其表述为

the set of concepts and practices that define a scientific discipline at any particular period of time

即在一个特定是其中定义科学准则的一系列概念和实践。

在这里我们可以将范式(paradigms)理解为一系列在特定时间、对特定对象的概念和实践。类似于模式(patten),但后者是对一些具体问题的技巧性总结。

《大秦帝国》中商鞅在给秦孝公讲强国之道时提过这个词,用来说明魏齐楚三国强国方式的不同

魏国范式 甲兵财货之强,齐国范式 明君吏治之强,楚国范式 山河广袤之强。而这三强,皆非根本之强,不足效法

1.2 编程范式

编程范式(programming paradigms)的概念在维基百科中解释为用来对不同编程语言分类的方式。

本节参考

解决一个编程问题需要选择一个概念(concept)。
每个范式是一系列concepts的组合,用来更高效或者简洁地解决特定问题,比如object-oriented 编程善于处理层次结构中有大量关联数据的问题。这样的组合我们这里包含27种。
每一种语言要么实现了其中一种范式,要么实现了多种,对于不包含的概念,该种语言就无法合适地处理。

该图中每个盒子是一种范式,箭头指的是从一种范式到另一种范式添加的concepts,可以看到两个看起来完全不同的范式可能只差一个concept(比如functional programming and object-oriented programming)。

其中状态(state)代表程序中对于时间的抽象表示,比如一个函数就是无状态的,相同的输入都会有相同的输出,对于有状态的又分为named state和unnamed state。

对于其中的concept,我们选几个介绍一下概念,更多概念可以参考Concepts, Techniques, and Models of Computer Programming ,这里有个下载链接

  1. cell和port
    这两个概念类似,都可以用来传递数据,其中cell适合原子操作时共享数据,port用来在active objects之间通信

  2. Lexically scoped closure

闭包是个很重要的概念(以至于面试时经常问),我们在这里重新认识一下。
从实现角度来看,一个闭包包含一个procedure和它外部的引用。
从编程者角度来看,一个闭包是一个被打包的工作(packet of work):一个程序可以在一个点将任何指令加入闭包,然后传给另一个点,并决定在任何点执行。执行的结果就像在创建的点执行一样。

图中闭包P在D上下文中实现,保存了对应上下文(也就是D)的引用,比如有一个叫x的named state。我们可以称p的环境将定义它的上下文封闭了起来( the environment of P is closed over its definition context)。在调用的位置,即c上下文,p会使用对上下文的引用。

  1. record 就是一个数据结构,可以用来访问各项数据

2 具体范式

2.1 声明式编程和命令式编程

声明式编程(declarative programming )和命令式编程(imperative programming)是两种基本的编程。

其中前者用来表示计算的逻辑,而不描述其控制流,比如xml。
后者使用更改程序state的语句,描述了程序如果操作,比如c。

2.2 面向对象编程

我们都知道c++在c的基础上实现了面向对象范式,另一个相关的概念面向过程编程可以看作是命令式编程的同义词。 从上一章可知,面向对象范式是在命令式编程的基础上增加了闭包的概念。

面向对象三大特点是

  • 封装(Encapsulation) 可以将数据和操作的函数绑定,从而实现信息隐藏
  • 继承(inheritance)继承的实现主要分两种,一种是基于类,另一种是基于原型,通过继承可以派生出新的类或对象,复用父类的属性和行为
  • 多态(Polymorphism)调用继承层次中的不同方法时,结果可能不一样

面向对象编程的设计原则和设计规范,参考这篇文章.

2.3 函数式编程

函数式编程(functional programming )比面向对象编程少了一个concept,即cell,因此纯函数本身没有状态,除了返回对应的值,是不应该有副作用的。 不过我们见过的函数不一定都是纯函数,比如有些函数中可能会带有修改ui的副作用。

想了解函数式编程更多,可参考Functional-Light-JS


完结撒花