前言
前面说一点想说的话,最近结束了毕业设计的答辩,成绩还算理想。因为毕设代码后端使用了NodeJS,所以阐述的时候提到了其函数式编程非常适合写异步回调。紧接着耿老师问了一个问题,让我讲讲什么是函数式编程,而我觉得没有当场讲的很清楚,答辩结束自行梳理了一下关于函数式编程的知识。
这篇文章会讲讲我理解的函数式编程。此外,非常感谢耿老师在答辩的当天下午就推送了自己讲解的一篇函数式编程相关的推文。
推文链接:Java中的Lambda表达式
看完老师的推文之后大致明白了Java中函数式编程思想。
Java中的Lambda表达式主要目的是在使用单接口(只含有一个方法的接口)匿名类时让代码更加简洁。Lambda表达式类似匿名函数,方法类型和名称都被去除,只留参数列表和方法体。 当然,在特殊的上下文中编译才能推断出具体实现的是哪种方法。
下面来说说我收集的函数式编程相关资料。
什么是函数式编程 Functional programming
函数式编程或称函数程序设计,又称泛函编程,是一种编程典范,它将电脑运算视为数学上的函数计算,并且避免使用程序状态以及易变物件。
函数程式语言最重要的基础是λ演算。
λ演算的函数可以接受函数当作输入(引数)和输出(传出值)。
比起指令式编程,函数式编程更加强调程序执行的结果而非执行的过程,倡导利用若干简单的执行单元让计算结果不断渐进,逐层推导复杂的运算,而不是设计一个复杂的执行过程。
典型的函数式编程语言
编程语言分类
纯函数式编程语言
- 强静态类型
- Concurrent Clean:Clean是用C语言写成的
- Haskell:函数是一等公民
- Miranda:采用惰性求值的概念
- 弱类型
- Lazy K
非纯函数式编程语言
- 强静态类型
- F#
- ML
- OCaml
- Scala
- 强动态类型
- Clojure
- Erlang
- Lisp
- LOGO
- Mathematica
- R
- Scheme
- 弱类型
- Unlambda
其他函数式编程语言
- APL
- XSLT
JavaScript函数式编程
为什么要了解JavaScript函数式编程呢,因为我是个前端(笑。
最近,函数式编程这样的概念出现的频率很高,之前很长时间OOP主导着业界,但是这种范式在JavaScript中使用比较笨拙,我们不得已常常使用this或者bind,apply这种可以改变上下文的方式来确定作用域,是有一定副作用的。
与命令式相比,函数式编程语义更加清晰,ES6标准对于函数式编程的支持越来越出色,诸如RxJS、React、Redux、ImmutableJS、lodash等“函数式”框架和像lodash/fp、Ramda这样的“函数式”编程库逐渐流行。
概述:JavaScript函数式编程是以函数作为主要载体的编程方式,用函数去拆解、抽象一般的表达式,从而增加代码的可复用性和可维护性。
常用的函数式编程模型:
- 闭包:保留局部变量不被释放
- 高阶函数:接受或者返回一个函数的函数
- 函数柯里化curry
curry 的概念很简单:只传递给函数一部分参数来调用它,让它返回一个函数去处理剩下的参数。 - 组合Composing:将多个函数的能力合并,创造一个新函数
总结
函数式编程还包括将其他的诸如普通函数结合调用、链式结构等,它们都可以理解成是一个范畴的,其本质都是以函数为载体,可以和OOP等一块理解,其实都是一种思想。
JavaScript一开始的语法就是从Scheme这种函数式编程语言借鉴而来。让函数可以作为参数、返回值、进行函数之间的运算,严格意义上像Redux、React Hooks这样的框架只是运用了接近函数式编程思想的东西。
所以对JavaScript的函数式编程,要懂得适可而止,做到不画蛇添足,不能引入副作用。
具体可以通过以下三点来自我约束:
- 不用单等号赋值
- 不用大量的
if
/for
语句 - 使用箭头函数
注:由于目前API函数式的完全支持还比较少,JavaScript对于尾递归的优化上的解决方案还有待深入。
PS:有人说面向对象编程就能像C 碾压C++ 般,摧残函数式编程。所以说函数式编程和C语言是竞争关系,这场没有硝烟的战役谁能笑到最后呢,还需要拭目以待。