之前在研究redux时候就接触锅函数式编程,但一直对于概念及其用法一知半截。终于时隔半年后抽个时间来总结下。
在开始之前先整理下需知的知识点:

  1. JS中的柯里化(currying)
  2. 编程语言的主要类型

    Common programming paradigms include imperative which allows side effects, functional which disallows side effects, declarative which does not state the order in which operations execute
    A programming paradigm is a fundamental style of computer programming. There are four main paradigms: imperative, declarative, functional (which is considered a subset of the declarative paradigm) and object-oriented.
    Declarative programming : is a programming paradigm that expresses the logic of a computation(What do) without describing its control flow(How do). Some well-known examples of declarative domain specific languages (DSLs) include CSS, regular expressions, and a subset of SQL (SELECT queries, for example) Many markup languages such as HTML, MXML, XAML, XSLT… are often declarative. The declarative programming try to blur the distinction between a program as a set of instructions and a program as an assertion about the desired answer.
    Imperative programming : is a programming paradigm that describes computation in terms of statements that change a program state. The declarative programs can be dually viewed as programming commands or mathematical assertions.
    Functional programming : is a programming paradigm that treats computation as the evaluation of mathematical functions and avoids state and mutable data. It emphasizes the application of functions, in contrast to the imperative programming style, which emphasizes changes in state. In a pure functional language, such as Haskell, all functions are without side effects, and state changes are only represented as functions that transform the state.
    Symbolic programming : is a paradigm that describes programs able to manipulate formulas and program components as data. Programs can thus effectively modify themselves, and appear to “learn”, making them suited for applications such as artificial intelligence, expert systems, natural-language processing and computer games. Languages that support this paradigm include Lisp and Prolog.

(维基百科)

使用百度翻译后 大意是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
常见的编程范式包括命令允许副作用,功能不允许副作用,说明它不状态的顺序操作,执行.
编程范式是计算机编程的基本风格。主要有四种范式:命令式、声明式、功能型(它被认为是声明范型的一个子集)和面向对象。
>声明式编程:是一种编程范式,它表达了计算的逻辑(没有解释它的控制流)。声明的领域特定语言(DSL)的一些著名的例子包括CSS,正则表达式和SQL的子集(选择查询,例如)许多标记语言如HTML,MXML,XAML,XSLT…常常声明。声明式编程试图把程序作为一组指令和一个程序之间的区别模糊化,以此作为对所需答案的断言。
>命令式编程:是一种编程范式,用改变程序状态的语句来描述计算。声明的程序可以同时视为编程命令或数学断言。
>函数编程:是一种编程范式,将计算作为对数学函数的评价,并避免状态变量和可变数据。它强调函数的应用,与命令式编程风格相反,它强调状态的变化。在一个纯粹的功能性语言,如Haskell,所有功能都没有副作用,和状态的变化,只表示为函数变换的状态。
>符号编程:是描述能够操纵公式和程序组件作为数据的程序的范例。因此,程序可以有效地修改自己,并似乎“学习”,使之适合于应用程序,如人工智能,专家系统,自然语言处理和计算机游戏。支持这种范式的语言包括Lisp和Prolog语言。
```
我理解的是:
1. 声明式编程:专注于”做什么”而不是”如何去做”。在更高层面写代码,更关心的是目标,而不是底层算法实现的过程。
ex: css, 正则表达式,sql 语句,html, xml…
2. 命令式编程(过程式编程):专注于”如何去做”,这样不管”做什么”,都会按照你的命令去做。解决某一问题的具体算法实现。
3. 函数式编程:把运算过程尽量写成一系列嵌套的函数(功能)调用。是一种编程范式,将计算作为对数学函数的评价,并避免状态变量和可变数据。它强调函数的应用,与命令式编程风格相反,它强调状态的变化。
函数式编程强调没有”副作用”,意味着函数要保持独立,所有功能就是返回一个新的值,没有其他行为,尤其是不得修改外部变量的值。
所谓”副作用”(side effect),指的是函数内部与外部互动(最典型的情况,就是修改全局变量的值),产生运算以外的其他结果。
([详细了解函数式编程请看阮一峰的函数编程初探文章](http://www.ruanyifeng.com/blog/2012/04/functional_programming.html))
4. 符号程序设计:是一个范例,描述能够操纵公式和程序组件作为数据的程序。因此,程序可以有效地修改自己,并似乎“学习”,使之适合于应用程序,如人工智能,专家系统,自然语言处理和计算机游戏。支持这种范式的语言包括Lisp和Prolog语言。
不了解这个留坑以后填
举个例子,了解下前三者的区别
现在有一个这样的需求让计算机做:
```text
(1+2) * 3 / 4

命令式编程可能这样做

1
2
3
var a = 1+2;
var b = a*3;
var c = b/4;

声明式编程式这样的

1
2
3
4
function compute(a,b,c,d){
return (a+b)*3/4
}
compute(1,2,3,4);

函数式的做法是这样的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//1 定义一个add函数,并将他柯里化
function add(a){
return function(b){
return a+b;
}
}
//2定义一个multiply函数,并将他柯里化
function multiply(a){
return function(b){
return a*b;
}
}
//3定义一个divide函数,并将他柯里化
function divide(a){
return function(b){
return a/b;
}
}
//4 将上诉函数合成一个函函数
function compose(add,multiply,divide){
return function(a,b,c,d){
divide(
multiply(
add(a)(b)
)(c)
)(d);
}
}
//5 计算
compose(add,multiply,divide)(1,2,3,4);