函数式编程与命令式编程
理解编程范式的演变及其如何推动了函数式编程的发展。
编程范式由构建软件的规则和设计原则组成。范式的变化意味着当前的软件开发策略中某些方面无法满足现代需求。例如,我们可能需要快速且可靠地处理多个任务和大量数据。CPU的速度并未提升——我们不能仅仅依靠编写代码,就指望新CPU发布后程序自动变快。相反,我们需要利用多核处理器甚至多台机器来处理任务。这就要求我们编写能够充分利用并发和并行特性的代码。然而,在命令式和面向对象语言中实现这一点非常困难。这只是这些常见方法可能失效的一个例子。让我们更深入地探讨命令式编程的局限性。

命令式语言的局限性
命令式语言具有共享的可变值。这意味着程序的多个部分可以引用同一个值,并且该值可以被修改。可变值在并发场景下存在风险,容易引入难以发现的错误。例如,来看一段 Ruby 脚本:
1list = [1, 2, 3, 4] 2list.pop 3# => 4 4# => [1, 2, 3] 5list.push(1) 6# => [1, 2, 3, 1] 7puts list.inspect 8# => [1, 2, 3, 1]
在本章中,我们将看到更多类似上面的代码示例。不必担心语法或语言的具体机制,重点在于理解其中的概念。
在这里,我们可以通过添加或删除元素来修改数据。现在设想一个应用中有多个部分在并行运行,并同时访问 list。如果在某个操作进行过程中,由于其他进程的干预导致该值发生变化,会发生什么情况?
这种行为难以预测,会给开发者带来困扰。因此,许多命令式语言提供了锁机制和同步工具来帮助我们管理变化。但这并非唯一解决方案。函数式编程提供了一个更优的替代方案。
迈向函数式编程

在本课程中,我们将学习匿名函数、自由变量与绑定变量,以及函数作为一等公民的概念。这些概念均源自阿隆佐·邱奇在20世纪30年代提出的λ演算计算模型。
λ演算是最小的通用语言,能够模拟任何图灵完备的现实计算。
只要一种编程语言支持λ表达式,就可以确定其受到了邱奇模型的影响。
使用像 Elixir 这样的函数式语言,我们可以更高效地利用多核 CPU,编写出更短且更清晰的代码。当我们采用函数式范式时,代码能与语言本身更好地协同工作。但这并非免费获得的。我们必须理解并遵循三个核心原则:不可变性、函数 和 声明式代码。
本章将详细探讨这些原则,并展示函数式基础如何更好地应对现代开发需求。