【关于本书】
本书旨在告诉你如何使用类型系统编写更好、更安全的代码。虽然大部分介绍类型系统的图书更加关注形式方面的讨论,但本书采用了偏向实用的做法。本书包含你在日常工作中可能遇到的许多示例、应用和场景。
【读者对象】
本书主要针对想要学习类型系统的工作原理以及使用类型系统来提高代码质量的程序员。你应该具备一些使用面向对象编程语言(如Java、C#、C++或JavaScript/TypeScript)的经验,还应该有一些软件设计经验。虽然本书的代码示例是基于TypeScript的,但是大部分内容是普遍适用的。事实上,本书的代码示例并非总是使用TypeScript特有的功能。在编写代码示例时,我尽可能让熟悉其他编程语言的程序员也容易理解它们。虽然本书会介绍各种技术来帮助你编写健壮的、可组合的、封装程度更好的代码,但是也假定了你知道为什么我们希望获得这些特性。此外,本书侧重类型系统的实际应用,因此涉及的数学理论较少,但是你应该熟悉基本的代数概念,如函数和集合等。
【本书的组织方式】
本书包含11章,涵盖类型编程的各个方面。
第1章介绍类型和类型系统,讨论它们为什么存在以及为什么有用。我们将讨论类型系统的类型,并解释类型强度、静态类型和动态类型。
第2章介绍大部分语言中都有的基本类型,以及在使用这些类型时需要注意的地方。常用的基本类型包括空类型、单元类型、布尔类型、数值类型、字符串类型、数组类型和引用类型。
第3章介绍组合,包括把类型组合起来定义新类型的各种方式,还介绍实现访问者设计模式的不同方式,并定义代数数据类型。
第4章讨论类型安全—如何使用类型来减少歧义以及防止错误。本章还介绍如何使用类型转换在代码中添加或移除类型信息。
第5章介绍函数类型,以及当我们获得了创建函数变量的能力后能够做些什么,还展示实现策略模式和状态机的不同方式,并介绍基本的map()、filter()和reduce()算法。
第6章以前一章为基础,展示函数类型的一些高级应用,包括简化的装饰器模式、可恢复的函数和异步函数。
第7章介绍子类型,并讨论类型兼容。我们会看到顶层类型和底层类型的应用,以及从子类型的角度看,和类型、集合和函数类型之间的关系。
第8章介绍面向对象编程的关键元素,以及什么时候使用每种元素,并讨论接口、继承、组合和混入。
第9章介绍泛型编程及其第一种应用—泛型数据结构。泛型数据结构把数据的布局与数据本身分隔开。迭代器支持遍历这些数据结构。
第10章继续介绍泛型编程,讨论泛型算法及迭代器的分类。泛型算法是能够在不同数据类型上重用的算法。迭代器用作数据结构和算法之间的接口,并且能够根据迭代器的能力启用不同的算法。
第11章介绍高阶类型、函子和单子的概念,以及如何使用它们,并为进一步学习提供一些建议。
本书中的各章以前面章节中的概念作为基础,故建议读者按顺序阅读。虽然如此,但是本书介绍的4大主题相对独立:前4章介绍基础知识;第5~6章介绍函数类型;第7~8章介绍子类型;第9~11章介绍泛型编程。
【关于代码】
本书以程序清单和嵌入在正文中的方式给出了许多源代码示例。这两种形式的代码都采用了等宽字体。有时候,代码还会被加粗显示,表示这部分代码相比该章前面的步骤发生了变化,例如,在现有的一行代码中添加了新特性。
在多数情况下,我调整了最初源代码的格式,添加了换行,调整了缩进,以适应版面空间。在少数情况下,即使这样调整后代码也无法放到一行,此时程序清单中会包含代码行延续标记()。另外,当在正文解释了程序清单中的代码时,常常会移除源代码中的注释。许多程序清单都带有代码标注,用于解释重要的概念。
本书的所有代码示例都可以在GitHub上获取,网址为https://github.com/vladris/programming-with-types/。生成代码时,使用了TypeScript 3.3版本,针对ES6标准,并使用了strict设置。
【前言】
我将多年间学习类型系统和软件正确性的经验汇聚起来,加以提炼,并辅以现实世界的应用,编写了这本实用的图书。
我一直对编写更好的代码有浓厚的兴趣,但是如果让我准确说出从什么时候开始走上这条道路,我会说是2015年。当时,我换了团队,想要快速学习现代C++。我开始观看C++会议视频,并阅读Alexander Stepanov关于泛型编程的著作,从一种完全不同的视角了解了如何编写代码。
与此同时,我在业余时间学习Haskell,一步步了解它的类型系统的高级特性。在使用函数式语言进行编程后,就能够很清晰地理解为什么随着时间的推移,更主流的语言开始采用函数式语言中的一些被认为理所当然的特性。
我阅读了关于这个主题的许多图书,包括Stepanov的Elements of Programming和From Mathematics to Generic Programming,Bartosz Milewski的Category Theory for Programmers,以及Benjamin Pierce的Types and Programming Languages。从书名就可以知道,这些图书更偏向理论/数学方面。在学习了关于类型系统的更多知识后,我在工作中编写的代码也变得更好了。类型系统设计的理论与日常生产软件之间存在直接的联系。这并不是一个革命性的发现:复杂的类型系统特性之所以存在,就是为了解决现实世界的问题。
我意识到,并不是每个程序员都有时间和耐心来阅读那些提供数学证明、讲解深入的图书。但我阅读这些书并没有浪费时间,这使我成为一名更好的软件工程师。我认为应该有这样一本书:以更加轻松的方式来介绍类型系统及它们提供的优势,并关注每个人能够在日常工作中使用的实际应用。
本书旨在全面介绍类型系统的特性,从基本类型开始,涵盖函数类型和子类型、OOP、泛型编程和高阶类型(如函子和单子)。我没有关注这些特性背后的理论,而是通过实际应用的方式来解释每种特性,说明如何以及何时使用这些特性来改进代码。
我一开始打算使用C++来编写代码示例。C++的类型系统十分强大,并且具有比Java和C#等语言更多的特性。但另一方面,C++是一个复杂的语言,而我不想限制本书的受众,所以后来决定使用TypeScript。TypeScript也有一个强大的类型系统,但是其语法更加容易理解,因此即使你使用的是其他语言,在学习本书的大部分示例时应该也不会有太大的难度。附录B为本书用到的TypeScript语法提供了一个速览表。
我希望你能享受阅读本书的过程,并学到一些可以立即用在项目中的新技术。