《Java函数式编程》出版啦
从2017年年初到年底,我的新译作《Java函数式编程》终于出版啦。这里简要地介绍一下本书,并放篇我为此书所作的译者序,安利一下。
简介
《Java函数式编程》并不是一本关于Java的书,而是一本关于函数式编程的书。作者由浅入深地介绍了函数式编程的思维方式,并引导读者通过易于掌握的例子、练习和图表来学习和巩固函数式编程的基本原则和最佳实践。读者甚至可以在阅读的同时编写出自己的函数式类库!
与《Java 8函数式编程》相比(这是一本Java 8的函数式用法的入门佳作),本书侧重的是函数式的思维与实践,而非是Java 8的语法。如果你是一位看完基础语法书后喜欢接着看“Effective”系列的程序员,那么本书就有几分类似于“Effective”版,只不过它讲的是函数式而非是Java 8的“Effective”。语言容易过时或被淘汰,但是思想永存。
译者序
有幸受邀翻译本书。初见书名,心中不免有几分疑虑,难道又是一本教你怎么使用Java 8 lambda来函数式编程的书吗?翻了几页,方觉自己大误。本书其实意在如何从零开始,逐步理清函数式编程的思维方式并编写基础类库,不仅授之以鱼,而且授之以渔。只不过由于Java的受众实在太广,所以才使用这门语言罢了。
函数式编程有一个至关重要的前提,那就是函数的输出只能取决于函数的参数(我们会在书中看到生成随机数的例子)。初看上去似乎与Java这门面向对象的语言不搭。但语言只是工具而已,正如你也可以在Haskell中编写命令式风格的代码。在一个不太复杂、甚至非并发的常规Java系统中,由于程序内部状态的改变,多次调用同一个方法的返回值很可能是不一样的,更不用说所带来的副作用了。函数式编程中,确定的输入决定了确定的输出,就意味着只要参数对了,结果一定在预期中。也就是说,函数式编程没有无法重现的bug。在这样的前提下,单元测试相对容易实现,而且能极大地增强你的信心。(想想你对目前所在项目的单元测试有多大的信心?)许多个这样的函数复合起来,在不改变信心的同时能够提供更多更强大的功能,进而带来更大的收益,如无状态的线程安全、必要时才计算的惰性求值、加快多次执行速度的记忆化等等。
传统的命令式编程是计算机硬件的抽象,源自图灵机,其实就是外部输入、内部状态、对外部的输出以及对内部状态的改变。函数式编程源自λ演算,即将变量和函数替换为或值表达式并根据运算符计算。函数式编程相比命令式编程代码更简洁、可读性更强,这是因为它的思维方式更倾向于描述要什么,而不是怎么做。所以学习过程反而更加自然,并且不需要多么高深的数学基础。可是我们也知道,软件开发没有银弹。新的方法论也会带来新的问题,需要运用新知识来解决。幸运的是,新知识的坑已经有人帮你踩过了,高阶函数、偏应用函数、复合函数、柯里化、闭包……软件开发从来不缺术语。幸好它们并非高不可攀,作者将会在第二章中扫清你的疑虑,并在后续章节中挑战惰性求值、记忆化、状态处理、应用作用还有actor等更高级的技术。你说Monad?作者才不告诉你它究竟是什么,但是看完本书你自然就领悟了。
函数式编程不是万能药。它有自己擅长的领域,也有自己的弱项。函数式编程是级别更高的抽象。高级别抽象带来的收益就是易读、好写,可是有些低级别的事情(如果你真的需要的话)可能就不容易完成。函数式编程没有副作用,导致无法完成输入/输出操作。尽管如此,你也会在本书中看到一些解决办法。函数式编程没有变量,因此无法改变循环的终止条件,故而没有循环,严重依赖于用递归来抽象循环。在某些情况下可能会影响性能,所以你还会在本书中看到一些性能与情怀之间的权衡。绝大部分的编程最佳实践都是针对某个特定的场景而言的。因此脱离业务场景直接讨论技术并不可取。拥有函数式编程的思维,你就拥有了解决问题的另一种选择,但是条条大路通罗马,千万别钻牛角尖。程序是对现实世界的建模,“不要让世界适应你的模型。让你的模型适应世界。”
致谢
感谢作者Pierre-Yves Saumont,不仅写了这样一本令程序员们受益匪浅的书,而且耗费精力维护本书的后续重构,还耐心地回答我对书中的疑问,使我有机会提高中文版的翻译质量。
感谢永恒的侠少和刘舫,让我可以集中精力专注于翻译之上,并让本书得以出版。
感谢瑞民,虽然世事变幻莫测,但是你始终扮演了非常重要的角色。
感谢家人和朋友们,我永远离不开你们的鼓励和支持。