范式指解决问题的方法,编程范式指用程序语言解决问题的方式。
整体上编程范式分为两个阵营:命令式 (imperative) V.S. 声明式 (declarative)。
1 命令式
命令式编程起源早,基于冯诺依曼结构,包含指令和指令的存储,通过控制状态来达成目标,核心是指令顺序。
包括 3 种常见编程范式:面向过程范式 OPP(Procedure Oriented Programming),面向对象范式 OOP(Object Oriented Programming),并行计算范式 (Parallel
Processing Approach)
面向过程式
强调在机器结构基础上描述执行过程,核心优势是过程的复用。典型语言:C/C++/JAVA/Pascal
int[] nums = new int[]{1,2,5,3,8};
int[] result = new int[nums.length];
int curidx = 0;
for (int num : nums) {
if (num > 5) {
result[curidx++] = num;
}
}
return result;
实现了从一个数组中检索大于 5 的数,过程是先构建一个返回数组,遍历当前数组中每个值,如果符合条件则添加到返回数组中。
面向对象式
强调基于问题抽象出对象,定义类和他们之间的关系,关注数据而不是过程。典型语言:JAVA/C++/Objective-C/VB/Python/Ruby
class Person {
private int age;
private String name;
}
class Employee implements Person {
private float salary;
}
人定义了年龄和名字两个属性,打工人是人的继承,不用再定义人拥有的属性,额外扩展了打工人的薪资。
并行计算式
强调多核的指令拆分和协作。典型语言:NESL,C/C++(一部分库函数支持并行计算)
function qsort(a) =
if (#a < 2) then a
else
let pivot = a[#a/2];
lesser = {e in a| e < pivot};
equal = {e in a| e == pivot};
greater = {e in a| e > pivot};
result = {qsort(v): v in [lesser,greater]};
in result[0] ++ equal ++ result[1] $
通过语言的并行计算能力,实现了快速排序。
2 声明式
声明式编程描述完成任务的计算逻辑而不关注控制流程,开发者的角色从思考如何完成计算转换到什么需要计算。
包括 3 种常见编程范式:逻辑范式 (Logic Programming),函数式范式 (Functional Programming)
,数据驱动范式 (Database Processing Approach)
逻辑式
强调问题的知识基础,机器学习很多也是基于逻辑范式。典型语言:Prolog
likes(bell,sports).
likes(mary,music).
likes(mary,sports).
likes(jane,smith).
friend(john,X):-
likes(X,sports),
likes(X,music).
第一段 likes() 引导的部分是知识基础,表达某个人喜欢什么。第二段定义 john 对朋友的要求,喜欢 sports 和 music。此时如果询问 friend(john,X) 即 john 的朋友是谁?会得到回答:marry,因为 john 对朋友的要求 marry 最匹配。这也是一段简单的机器学习逻辑,人工智能本质上在做的是类似这样的逻辑范式编程。
函数式
植根于数学,且与语言强相关,强调执行一组数学函数的流程。主旨是将计算过程和数据解耦,用函数来封装细节实现。典型语言:JavaScript/Perl
def get_users(age: int) -> list:
ret = []
for user in users:
if user['age'] > age:
ret.append(user)
return ret
函数实现了筛选年龄大于输入值的所有用户。
数据驱动式
基于数据和其流转。典型语言:SQL
SELECT *
FROM users
where phone like '135%';
查询所有手机号以 135 开头的用户。
总结
编程范式分为两个阵营,命令式编程关心如何计算 how,声明式编程关心计算什么 what。不同的编程范式不是泾渭分明的,往往某种语言的实现会同时用到多种范式,例如 JAVA 以命令式的面向对象为主,掺杂面向过程、函数式等其他编程范式。
重要的不是区分不同的编程范式,而是灵活的应用编程范式在具体的场景下高效的解决问题。