<译> 写给程序猿的范畴论 · 序

原文见 http://bartoszmilewski.com/20...程序员

我打算为程序猿们写一本讲范畴论的书已经有一段时间了。注意,受众不是计算机科学家,而是程序猿——是工程师,而不是科学家。这听起来挺疯狂,我也有些坐卧不安,可是我没法容忍科学与工程之间存在着巨大的鸿沟,更况且我自身的工做也是常常须要我在这两个世界中穿梭。不过,要解释一些东西,总让我感受很是窘迫。我很是敬仰 Richard Feynman(理查德·费恩曼),在讲授知识方面他是深刻浅出的大师。我不是 Feynman,但我会尽力。我从发布这篇序言开始,激励读者学习范畴论,但愿能引起一些讨论并获得一些反馈意见。算法

下面我要用几段文字让你相信,这本书是写给你的。根本不必担忧它是几乎会耗尽你全部的业余时间的一门最抽象的数学。编程

个人乐观来自一些观察。首先,范畴论是至关有用的编程思想宝藏。Haskell 程序猿们已经涉足此境好久了,其中的一些思想正慢慢的渗入其余语言,只是这一过程是很是缓慢而已,咱们须要使之加速。segmentfault

其次,有许多种数学,它们面向不一样受众。你可能不喜欢代数学,但这并不意味这你没法喜欢范畴论。我会向你展现,范畴论很是适合程序猿的思惟。由于范畴论处理的对象不是计算细节,而是结构。它处理的是使程序可复合的结构。服务器

复合是范畴论的精髓,它也是范畴论自身定义的一部分。我会证实编程的本质是『复合』。咱们一直都在组合一些东西,这种行为从好久之前一群伟大的工程师提出子程序的时代就开始了。好久之前,结构化编程原理掀起了编程的革命,它立足于代码级别的复合。伴随面向对象编程而来的则是对象的复合。函数式编程不只仅设计函数的复合与代数数据结构,它还提供了对并发计算的支持,这是其余编程范式难以实现的。网络

第三,我有秘密武器,一把庖丁之刀,我要用它将数学大卸八块使之成为程序猿的美味佳肴。若是你是数学家,你不得不大胆假设,当心求证,严格的构造你的定理,而后产生令外人难以卒读的论文与专著。我是训练有素的物理学家,在物理学中,咱们使用着并不正规的推理来取得使人激动的发现。数学家们嘲笑伟大的物理学家 P. A. M. Dirac 为求解一些微分方程而提出的狄拉克 δ 函数,可是当他们发现了一个叫作广义函数论的新的数学分支时,他们就不笑了,由于广义函数论只是对 Dirac 观点的一种形式化描述。数据结构

固然,采用不严肃的论证方式很容易产生谬论。所以在这本书中凡是遇到不正式的论证时我会尽力肯定其背后存在着相应的实际数学理论。我床头有一本被我翻的破破烂烂的 Saunders Mac Lane 写的《Category Theory for the Working Mathematician》。架构

译注:Category Theory for the Working Mathematician,可翻译为『面向一线数学家的范畴论』?并发

因为这本书是写给程序猿的范畴论,所以我将会用计算机程序代码展示范畴论的主要概念。你可能会担忧函数式语言会比传统的命令式语言更接近数学,并认为前者为此已经提供了更多的抽象能力,因此想固然的认为只有学习了 Haskell 方能将范畴论的能量做用于现实,或者认为范畴论在函数式编程范式以外没有什么用处,这些见解并不正确。我会提供大量的 C++ 的例子,只不过你得容忍一些丑陋的语法,须要在繁琐的代码中探寻清晰的模式,而且在更高层抽象的场合不得不作一些复制与粘贴的工做,不过这也正是大部分 C++ 程序员常常干的事。函数式编程

不过,你也没法脱离 Haskell 的羁绊。虽然没有必要成为一名 Haskell 程序猿,但你须要将 Haskell 做为一种草图性的语言,用于描述那些 C++ 示例的实现思想。这也正是我当初开始学习 Haskell 的所用的方法。Haskell 简洁扼要的语法与强大的类型系统,对于理解与实现 C++ 模板、数据结构与算法很是有帮助。固然,我不可能要求读者事先以已经了解 Haskell,我会逐步介绍 Haskell 的知识,而且会对我所用到的那部分 Haskell 代码给出详细的解释。

若是你是一名有经验的程序员,可能会自问:即便不懂范畴论与函数式方法,我也照样写代码,彷佛没什么必要学习它们。的确如此,不过你没法阻止正在侵入命令式语言的那股沉稳的函数式潮流。即便是 Java,面向对象编程的坚固堡垒,也拱手请来了 Lambda。C++ 也正在大踏步前进,如今每隔三五年就发布一个新标准,它正在尝试遇上这个正在变化的世界。这一切都在为一场变革而准备,这种变革,用咱们物理学家的术语可称为相变。若是你持续的烧水,它最终会沸腾。咱们如今正处于青蛙的位置,必须决定是在升温的水中继续游动,仍是开始做出其余抉择。

热水中的青蛙

驱动编程范式产生巨大变革的力量之一是多核革命。主流的编程范式——面向对象编程已经难以胜任并发与并行计算领域,它只会形成危险且充满 bug 的设计。数据隐藏,是面向对象的基本前提,一旦对象被共享且被修改,就会形成数据竞争。将数据与互斥锁组合起来看似是个不错的解决方案,但不幸的是,互斥锁不能组合,而且一旦在数据竞争中出现死锁,程序很是难以调试。

对于非并发计算,软件系统日益递增的复杂度也正在炙烤着命令式编程范式。简而言之,反作用正在失去控制。有反作用的函数很便捷又易于编写。原则上,有反作用的函数所产生的影响可在函数名以及注释中予以标明。一个叫作 SetPasswordWriteFile 的函数显然在修改某种状态并产生反作用,对此咱们已经很是习惯且不觉得然。只有当咱们开始将这些有反作用的函数层层组装到一块儿,事情才开始变得棘手。反作用自己并不坏,可是将它们塞到一个大尺度视图中,咱们很难再看清它们,它们便脱离了咱们的掌控。彻底与反作用打交道的命令式编程范式才是元凶。

硬件的变化与软件复杂度的增加都在迫使咱们从新思考编程的根本思想。正如欧洲最宏伟的哥特式大教堂的建造者那样,咱们正在面对着原料与结构的限制而磨砺着咱们的技艺。法国的博韦有一座未完工的哥特式教堂,它就是人类与限制做斗争的见证。这座教堂的设计企图在高度与采光方面击败全部的教堂,可是建造中却出现了一系列的崩塌。当时不得不用钢梁木柱临时作成支撑架构来阻止崩塌,但于事无补,由于不少东西在设计上就是错的。从现代的视角来看,博韦教堂是个奇迹,其至关多的一部分哥特式结构已经成功的建造了出来,这在那个没有现代材料科学、计算机建模、有限元分析甚至没有普通的数学与物理的时代显得有些难以想象。我指望咱们的后代也会敬佩咱们在构建复杂的操做系统、网络服务器以及互联网架构中展示出来的技术。绝不客气的说,他们理应如此,由于咱们是在脆弱的理论基础上完成的这一切。可是,若是咱们想继续前进,那么就必须修正现有的理论基础。

博韦教堂用于阻止崩塌的临时架构

下一篇 -> 范畴:复合的本质

相关文章
相关标签/搜索