当下,尤其是在前端,函数式编程(FP)已成显学。然而,究竟什么是函数式编程?λ表达式、递归、不可变、惰性求值、Monad……什么特性能代表 FP?哪些特性是 FP 语言有而其他语言没有的?哪些特性是某些 FP 语言独有的,哪些特性是大部分 FP 语言共有的?
据我所知,最流行的 FP 语言有两类:以 Scheme 为代表的 Lisp、以 Haskell 为代表的 ML。再取 C 作为非 FP 语言的代表,JavaScript 为流行的语言的代表,在下表中对比其特性。O 为支持,空为不支持。我基本不会这些语言,可能有错误或列举不完整。
特性 | Scheme | Haskell | JavaScript | C |
---|---|---|---|---|
函数一等公民 | O | O | O | O |
闭包(λ表达式) | O | O | O | |
默认柯里化 | O | |||
可变参数 | O | 差强人意 | O | |
词法作用域 | O | O | O | O |
Let 表达式 | O | O | ||
尾递归优化 | O | O | 事实上没有 | 支持但不保证 |
垃圾回收 | O | O | O | |
过程宏 | O | 扩展支持 | ||
自定义运算符 | 差强人意 | O | ||
无副作用、惰性求值 | O | |||
模块 | O | O | O | 可以说没有 |
模式匹配 | 可以说没有 | O | 无法判断 | |
静态类型 | O | O | ||
ADT | O | |||
call/cc | O | 可以说没有 |
综上所述,FP 语言共有的特性中,已经流行的有:闭包、可变参数、垃圾回收、模块。未流行的有:Let 表达式、尾递归优化 、过程宏、自定义运算符。
非常神奇啊!这些重要特性似乎和常见认知中的 FP 联系不很大。究其原因,Lisp 和 Haskell 是两个极端,动态类型与静态类型、严格求值与惰性求值,都是对立的。常见认知中的 FP 更接近 Haskell。不过,看看这些 FP 语言共有且未流行的特性,确实都是重要特性,希望能早日普及开来。