1. 什么是编程范式
编程范式是一类典型的编程规范。一方面提供了工程师对实体的建模方法,将物理世界与代码关联起来;另一方面也提供了工程师对代码程序的理解思路。
编程范式与编程语言属于多对多的关系。一种编程语言中,可能包含多种编程范式,例如,C++ 包含面向过程、面向对象等。一个编程范式,也有可能被多种编程语言实现,例如,JavaScript、Scale、Python 等都支持函数式编程。
2. 几种常见的编程范式
一句一句告诉计算机怎么处理。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| package main
import "fmt"
func main() {
var a int = 1
LOOP:
if a < 10 {
a++
goto LOOP
}
fmt.Printf("a = %d\n", a)
}
|
仅告诉计算机想要什么,常见的 DSL 语言都是声明式的,例如 SQL、HTML 等。
1
| SELECT * FROM Sites WHERE domain='www.chenshaowen.com'
|
拆分模块,借助循环等增加控制逻辑。
1
2
3
4
5
6
7
8
9
10
11
| package main
import "fmt"
func main() {
var a int = 1
for a < 10{
a ++
}
fmt.Printf("a = %d\n", a)
}
|
基于结构化,强调函数调用。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| package main
import "fmt"
func loop(a int) int{
for a < 10 {
a ++
}
return a
}
func main() {
var a = loop(1)
fmt.Printf("a = %d\n", a)
}
|
用类抽象实体,用对象表达实体。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| #!/usr/bin/python3
class Parent:
def myMethod(self):
print('调用父类方法')
class Child(Parent):
def myMethod(self):
print('调用子类方法')
c = Child() # 子类实例
c.myMethod() # 子类调用重写方法
|
将与模块无关的事情,放到外部完成,常见的实践方式是装饰器、中间件。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| def mydeco(func):
print('do some things')
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
@mydeco
def hello():
print('hello')
if __name__ == "__main__":
hello()
|
规定一组必须实现的方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| package main
import "fmt"
type Duck interface{
ToDuck()
}
type Dock1 struct{
}
func (d Dock1) ToDuck(){
fmt.Println("ga...")
}
func main(){
var d Duck
d = new(Dock1)
d.ToDuck()
}
|
用无状态的函数组合来描述程序逻辑。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| package main
import "fmt"
func add(a, b int) int {
return a + b
}
func multi(a, b int) int {
return a * b
}
func myCal(a, b func(int, int) int, c, d int) int {
return b(a(c, d), a(c, -d))
}
func main() {
var result = myCal(add, multi, 5, 1)
fmt.Println(result)
}
|
3. 为什么选择函数式编程
管理复杂度是软件工程面临的挑战之一。对于工程师来说,管理程序运行的状态是编程的难点。函数式编程,强调的是无状态,除了 IO 处理,不需要维护程序本身的状态。
函数式编程通常会借助声明式范式,以更接近人类语言的描述,告诉计算机做什么。而不是让人去模仿计算机的思考方式,一条指令一条指令地告诉计算机怎么做。
由于函数式编程不维护状态,不存在锁的问题,并发问题可以在编译器、解释器层面解决,大大降低了编写高并发程序的难度。
轮子总在被重新发明,很多思想在计算机发展的早期就已经出现,但不一定总有机会走到普罗大众面前。函数式编程、通信顺序进程等都是如此,包括云计算,风格总在轮换,具有一定的周期性。
4. 函数式编程的关键字
输出仅取决于输入。
函数可以被计算结果替代,而不影响调用它的程序。
不依赖外部状态。
需要时才进行求值。
匿名函数,没有名字的函数。
将多参数函数改造为返回单参数、并能继续接收剩余参数的函数过程。
接受函数作为参数或者返回函数的函数。