自上一本译作《Elixir 程序设计》出版已经过去了三年。Elixir 也从 1.2 版本更新到了 1.10。官方一直保持着每半年更新一个大版本的节奏。这些更新版本中,关于语法的变化和增强越来越少,针对库、工具链、使用体验和性能相关的更新越来越多,特别是 1.9 版本, José Valim 声称 Release 是最后一个计划中的特性。为 Elixir 语言日臻完善而感到高兴。
很多人把 Elixir 比作 Erlang 平台的 Ruby。诚然 Elixir 的作者和贡献者们从 Ruby 借用了许多语言设计。而 Ruby 就编程体验说是令人惊艳的,其动态、简洁、元编程都是 Java/Golang/Python 这些同时代流行语言所不具备的。当然 Ruby 也有硬伤,比如性能和并发。Elixir 选择将其基座造在 BEAM(Erlang VM)之上,BEAM 以 9 个 9 的可用性(31 毫秒/年的宕机时间)而著称。从并发上看,Actor 模型曾经是 Erlang 的优势之一,但今天 Rust 的 Actix 和 Java 的 Vert.x 性能测评甚至比 Erlang 要好,而 Erlang 真正的优势在于抢占式调度带来的低延时和软实时性。Elixir 的设计目标是让其有更高的可扩展性,更高的生产力,同时保持跟 Erlang 生态圈的兼容性。
Elixir 官方将其定义为 “一种用于构建可伸缩、可维护应用的动态、函数式编程语言”。下面我们就上述四个关键字来谈谈 Elixir 的与众不同。
相比于大家熟悉的面向对象(OOP),函数式编程范式(FP)强调程序执行的结果而不是过程,倡导利用若干简单的执行单元让计算结果不断渐进,逐层推导复杂的运算,而不是设计一个复杂的执行过程。每一个函数的结果只依赖于函数的参数,除了参数之外的任何数据都不会影响执行结果。严格的函数式语言要求函数必须无副作用。
而 Elixir 更有特色的函数式相关特性是数据结构不可变、模式匹配和管道。数据结构不可变要求每次都通过创建新的数据结构来修改已有的数据机构。而真因为这一点才能保证被传入的结构复杂的参数是完全不可变的。模式匹配让我们用新的视角去看待赋值和判断。这个特性不仅能够对数据结构进行解构,还能够根据函数的入参对方法逻辑进行拆分,使得代码更加清晰。管道只是一种类似链式调用的语法糖,借助于管道可以更专注于数据变化和流动,有别于 OOP 编程中的任务委派。Elixir 的这些语法特性是非常直观的,可以非常轻松地入门并写出清晰而易于维护的代码。
关于动态最直观的理解是动态类型。Elixir 是一种强动态类型语言,Elixir 中的类型都是在运行时才被推断出来的,也可以使用类型规格(typespec)在编译期间声明函数的签名和自定义的类型,使用类型规格声明函数之后,Erlang 的工具就会对源代码进行静态的类型检查,提前暴露出代码中类型不一致的问题。这样做的好处是,你可以获得静态类型的大部分优势,又不会失去动态类型所带来的灵活性。
大多数基于解释执行的动态语言都支持 eval 函数,eval 提供另一种动态,执行一段运行时才能确定的代码片段。通常来说程序操作数据,而这种能通过程序修改程序的方式我们称之为元编程。Elixir 通过宏开放了对 AST 的操作能力,而非类似于 C 语言宏那种编译期代码文本的直接替换。元编程也是 Ruby 和 Rust 的重要语言特性,其提供的强大表达能力,是让这类语言受追捧的原因之一。他让程序,特别是框架代码更加简洁。
最近两年一直在从事 FaaS 相关的研发工作,如今容器技术如火如荼,无服务计算(Serverless)方兴未艾,“以应用为中心”成为一种新的架构理念。从云原生生态的视角看,Docker/K8S/Serverless 等一些列基础设施都在以语言无关的方式回答可伸缩和可维护的问题。反观 Elixir,开箱即用依赖安装、构建和发布工具链、面向高并发的 Actor 模型以及构建大型可伸缩、热更新的 OTP 框架,显得小而美。在本地开发和部署到云上的版本是无差异的,而且是从语言层面,原生工具的层面就开始考虑这些问题,在业务逻辑和健壮应用之间没有割裂,不需要学额外的框架,更不需要熟悉纷繁的第三方平台。
掌握 Elixir 语言也许目前不能给您的简历添彩,让你在职场获得更多的溢价。但学习 Elixir 可以让你以不同的视角去看待函数式、可变、并发和高可用。软件工程最大的挑战是:持续满足业务复杂度的同时,保持工程的可维护性。而 Elixir 给出了从语言层面出发的系统性解法。虽然这门语言尚未流行起来,但是一点也不妨碍她优秀。
感谢编辑徐定翔给予的信任和耐心,我才得以顺利完成本书翻译。也感谢 Elixir 上海社区的同学们,特别是组织者 Tony,正因为有你们,我们可以在漫漫长路上结伴同行。由于水平和时间有限,书中有疏漏或者不尽人意之处,敬请广大读者批评指正。
杜万,2020 年 2 月 22 日于上海
《函数式编程入门:使用 Elixir》