如何评价Functional Programming in Scala 这本书?

http://www.amazon.com/Functional-Programming-Scala-Paul-Chiusano/dp/1617290653

江湖人称“Red Book”,目前还有最后一个section没看,个人感觉有些习题难度还是很大的,看完后应该算是对FP入门了,但是想要搞懂scalaz,type-level 等还是需要进阶的学习。

这本书有两个特点:

1. 没有很学术化的讲解,比较通俗易懂

2. 一直强调 "好,现在请合上书本,自己想想该如何设计才能体会如何取舍,然后再对照此书的内容自己比较一番" :)

注意:这不是一本讲Scala的书,这是一本以Scala为介质来讲FP的书

[Edit]: 贴一下Edward Kmett大神在quora上对此书的书评: Reviews of: Functional Programming in Scala (2014 book)

大意就是:“Paul 和 Runar 两人FP的造诣还是不错的,也是出于对他俩水平的信任,我才辞了之前工作跟他俩一起在同一个公司干活,因此也是看着这本书如何写出来的。我觉得这本书最好的地方就是它用Purely Functional Style来展示FP。不能给5星的原因就是scala本身不是一个pure的语言,Martin Odersky等人也不倡导纯pure, 而我本人是倡导pure FP的。。。”

呵呵,貌似也没提到啥干货 (我是说上面的书评里没啥干货)。


这本书比较奇葩的一点就是找了我来写序,而我可能是全中国程序员圈子里最不适合给《Scala函数式编程》写序的人。

三年前我写过《Scala七大死穴》,算是把Scala批判了一番。 前几天我则在准备 ThoughtWorks 咨询师大会上的讨论话题《没有函数的函数式编程》,又要杯葛函数式编程的样子。

看起来,我无论对Scala还是对函数式编程,都没什么好评嘛。宏江莫不是疯了,居然要我来写序?

等等,事情似乎不是这样。 最近几年, ThoughtWorks 的客户在越来越多的项目中采用了 Scala 技术栈,ThoughtWorks 也孵化出了若干基于 Scalaz 的开源项目。 我本人也在这些项目中起到了一些作用。

为什么我会做这些“口嫌体正直”的事呢? 这得从十年前说起。

我最早接触函数式编程是在 C++ 中。 C++ 和 Scala 一样,也是一门多范式语言。 C++ 的标准库 和 Boost 都提供了许多函数式编程的设施。 但是,在我职业生涯初期,给我留下深刻印象的函数式编程库要数 Boost.Egg 。

利用 Boost.Egg ,你可以写出 my_list|filtered(is_not_X)|filtered(is_not_Y) 这样的代码。 你会注意到这种用法和 Scala 标准库非常相像, 它大致相当于 Scala 的 myList.filter(isNotX _).filter(isNotY _), 这种 filter 的用法,本书第 47 页也有讲解。

Boost.Egg 的另一个特点是“非侵入”,比如上例的 filtered 函数,本身并不是 my_list的成员。 相反,我们通过重载 |运算符给原有的类型添加新功能。 这种做法在 Scala 里面相当于隐式转换,本书 107 页的例子正是利用隐式转换,给字符串添加了中缀操作符。

虽然 Boost.Egg 没能流行起来,但对我个人而言很重要,因为它很大程度塑造了我对代码的品位。

有趣的是,Boost.Egg 的作者 Shunsuke Sogame 近年来的开源项目,都是些 Scala 项目,可能这也是因为 C++ 和 Scala 非常相似的缘故吧。

另一个对我代码品位影响很大的技术是 Lua 中的协程 (coroutine)。 Lua的作者 Roberto Ierusalimschy 把协程称为“单趟延续执行流”(One-shot continuation)。 有了协程或者延续执行流,程序员可以手动切换执行流,不再需要编写事件回调函数,而可以编写直接命令式风格代码但不阻塞真正的线程。 我的前东家网易在开发游戏时,会大量使用协程来处理业务逻辑,一个游戏程序内同一时刻会运行成千上万个协程。

而在其他不支持协程或者延续执行流的语言中,程序员需要非阻塞或异步编程时,就必须采用层层嵌套回调函数的CPS(Continuation-Passing Style)风格。 这种风格在逻辑复杂时,会陷入“回调地狱”(Callback Hell)的陷阱,使得代码很难读懂,维护起来很困难。

Scala语言本身并不支持协程或者延续执行流。 因此,一般来说,程序员需要非阻塞或异步编程时,就必须使用类似本书178页的技术,注册回调函数或者用 for/yield 语句来执行异步操作。 如果流程很复杂的话,即使是 for/yield 语法仍然会陷入回调地狱。

我对 Scala 开源社区的贡献之一是 stateless-future。 这个库提供了一些宏,实现了延续执行流,可以把命令式风格的代码转换成 CPS 风格。 通过这种做法,程序员不再需要手写本书178页那样的代码了,编写的代码风格更像普通的 Java 或者 PHP 风格,直接像流水账一样描述顺序流程。

后来,我把这种避免回调函数的思路,推广到了其他用途上。比如,我开发了基于 Scala.js 的前端框架 Binding.scala。使用 Binding.scala 的用户,编写普通的 HTML 模板,描述视图中的变量绑定关系,而不需要编写高阶函数就能做出交互复杂的网页。

而我的另一个开源库Each,则更进一步,支持一切 monad 。大多数情况下,使用了 Each 就不需要编写任何高阶函数,我称之为“没有函数的函数式编程”。 这意味,本书11章到15章的全部内容,你都可以直接编写类似 Java 的命令式语法,而 Each 则自动帮你生成使用 monad 的代码。

总之,我是 Scala 函数式编程的死对头,我写的 Scala 库,恰恰是为了避免使用本书中敦敦教导的各种高阶函数。如果你是个 Java 程序员,想在最短的时间内用 Scala 开始“搬砖”,那么,从实用角度出发,我建议你合上本书,直接用 Each 即可。因为,虽然 Each 最终会生成 Monad 风格代码,但是,本书中涉及的使用高阶函数的细节,就像汇编语言一样,就算你不知道也照样可以干活。

不过,如果你是个求道者,追求编程艺术的真理,希望刨根到底,理解函数式编程的内在理论和实现机制,那么本书很适合你。

这本书绝不轻易放过每个知识点,全书包含有大量习题,要求你自己实现 Scala 标准库或者 Scalaz 中的既有功能。所以,当你读完本书,做完习题后,虽然你的应用开发能力并不会直接提升,但你会体会到构建函数式语言和框架时的难点和取舍,从而增进你的框架开发和语言设计的能力。

ThoughtWorks Lead Consultant 杨博

参考

  • Boost.Egg
  • 关于 Lua 中的协程,参见A. L. de Moura, N. Rodriguez, and R. Ierusalimschy. Coroutines in Lua. Journal of Universal Computer Science, 10(7):910–925, 2004.
  • 关于延续执行体的历史,参见Reynolds, John C. (1993). "The discoveries of continuations" (PDF). Lisp and Symbolic Computation 6 (3/4): 233–248.
  • 关于 Scala 异步编程的“回调地狱”问题,参见Business-Friendly Functional Programming – Part 1: Asynchronous Operations


谢邀.

之前在Haskell Book 这本书怎么样?的回答里提到FP in Scala适合作为学习Haskell的第二本书, 原因简单来说就是这本书相对于LYAH这本第一本书来讲了更多关于Functional Programing的东西, LYAH对于基础Haskell概念讲解得不错, 但是看完之后对于现实世界的问题还是手无寸铁的.

展开来说以前还是来点八卦, 之前有一篇东西讲他们公司用Go取代Scala, 因为里面的人要么把Scala当Better Java使, 要么就喜欢用Scalaz这种东西, 这也代表了Scala 社区里面的两大流派. Martin曾经说过“Scala is a gateway drug to Haskell”, 中毒有点深的一堆人搞了个typelevel.scala之, 还fork出来了 typelevel.scala. 那这本书的两个作者是哪一个流派的呢, 适合学Haskell的看的还用说当然是后者了, 不过Paul Chiusano 大神已经去探索下一代的编程环境了(Unison), Rúnar Bjarnason大神最近还在讲很多我看不懂的东西, 在翻machine的资料时也看到他的名字, 估计跟kmett大神认识...

回到正题...这不是本讲语言的书, 而是将范式的书, 讲范式的最好方式就是问题导向, 借助某个语言来对问题建模, 展现这个范式是怎么解决问题的 (当然用特定的语言来展现的话难免会夹带点私货, 而且什么是OOP, FP也说不准, 大概是这个意思就是).

FP in Scala就是用这个模式来写的, 第一章安利一番, 第二章扯点语言特性, 第三章开始进入重点, 数据结构跟数据抽象(在FP里面是ADT)是对问题建模的基础, 这一章把ADT的构造跟解构放在一起讲弥补了LYAH没有强调的一点东西.

第四章讲Error Handling, 把Maybe, Either放在一起讲, 没有一天到晚跟你说这个是Functor又是Applicative而且是Monad哦, 我们要解决的是错误处理的问题!

第五章讲Lazy, 虽然这章对理解Haskell的Lazy没什么帮助, 看完也不知道理解是WHNF之类的, 不过这一章讲了Lazy可以模块化代码, 提高可组合性, 把控制流分离出来, 关于这些我写了个答案也体提及过 Lazy computation 在实际应用中有什么妙用?

第六章讲state monad (再见

第二部分开始涉及到些有点高级的内容, 或者说写实际代码的时候真正有点卵用的内容...

...

写了这么多, 最后我想说其实我只随便翻了下这本书...

p.s

前段时间看到 http://hongjiang.info/archsummit-beijing-2015/ , 发现@hongjiang 已经在翻译 FP in Scala


我觉得这本书非常好。我在Verizon工作,我们整个Project有几十个Web services,大概有7,8个scala fp community比较知名的developer,其中包括Runar(在全美国这么多厉害的developer在同一个公司也不多见的),所以有些projects非常fp(毕竟水平参差不齐,有些repo就没法看)。我在去年五月加入Verizon之前对fp几乎一无所知,进入Verizon之后非常有幸遇到两位特别厉害的Developer,一位是Cats(scalaz的successor)的maintainer,一位是fs2(Scalaz-stream)的maintainer,跟他们一起写project代码很多时候不明白为什么要这样。一般他们会很耐心解释,但有些东西我会用了,理解并不深,比如特别基础的referential transparency。我最近才开始看fp in scala,虽然才看了前几个chapter,但是觉得帮助非常大。Runar的一些演讲也非常推荐,比如关于interpreter pattern和free monad的演讲。

-----补充----

刚从Typelevel/Nescala回来,特别想要在中国推广FP,于是想要开个Blog分享各种学习心得。我在微博写了第一篇文章,大家可以在我的知乎Profile上看到微博链接(貌似我直接复制粘贴微博链接不被允许。如果有别比较好的的中文tech blog网站,please let me know)。


这本书应该算是函数式编程的入门吧。

如果把scala作为一门语言来学习的话,programming in scala算是初窥门径,看完之后只能把scala当java用,就好像高炮打蚊子,自己也会觉得别扭。

The red book看完之后呢,简直就像打开了黑暗之门,各种黑魔法蜂拥而出。原来小样scala你还有这一面啊。你的好奇心又会变得无法抑制,FP就好像海洛因一般,吸引着你继续去看犯愁(范畴)论之类的玩意儿。

就好像大脑受到永久性损伤一样,你对代码应该如何组织的观念会发生不可逆的变化。scalaz/typelevel/...源代码中的奇技淫巧让你流连忘返。Haskell也马上就进入了你的todo list。


之前看过Scala标准库和spark的实现,有很多疑惑,这本书帮我解答了。


我是先学haskell的,学到MonadTransformer卡住了。。。

后转投Scala,掌握无压力。

《Functional Programming in Scala》 就是给想学scala的OO程序员补上haskell那课的~~


中文版马上就出了,是 @hongjiang 翻译的!【一图胜千言,我终于不用以死谢罪了……】


是一本入门的好书. 书写的很简单,完成习题可以攒一些编程经验.但这些经验有点像写数据结构程序获得的经验. 感觉并没有楼上说的那么神奇。


以当时FP零基础的经历读这本书(lamdba闭包还是会用的)的感觉是:

  • 第六章之前:做习题很开心,不懂就看答案,收获很多
  • 第六章需要反复读,但是第六章最后突然用for推导写state monad,用了set,get,modify之类的东西的时候还是很难懂的
  • 第六章之后的章节只有少数概念能看懂了,或者就是似懂非懂,感觉不佳

之后找来haskell的书,看到monad transform看懂,回来再看这本scala小红书,心情舒畅啊.

建议如果读小红书第六章之后很吃力的同学,又想学FP,赶紧去学haskell.

当然haskell也确实难学,不过那就是另外一个故事了.....


1, 如果打算购买,建议直接看英文版,因为翻译过来让人更糊涂

2, 书是好书,对里面的习题从思考到解决掉它们的过程会让你发现这本书很值得


这是一本非常棒的书,可惜我只看了几章,就先放着了,因为后续重点没放在Scala上了。


这是唯一一本牛气到 Amazon上只有纸版的 Scala书


我入门函数式编程就是看这本书,中间卡住了好多次,感觉还是挺有难度的。

坚持做里面的习题,完成后会对函数式编程有一个全新的认识。

看完后我又看了haskell,竟然也能理解一点了。


同意有个回答 先学haskell再学scala 会觉得任督二脉被打通的感觉


这书看了大部分。

关于书的内容:

1 对Monad,functor这些讲的很清楚,从代码出发的讲解对理解很有帮助。

2 书里面的例子和习题都有代码给出,这点非常好。


很好的一本书

关于中文版

看了预告之后期待了很久,很遗憾到手发现各个部分翻译质量参差不齐,翻得差的部分下限很低。

而我怕读下去会无法及时意识到哪些是翻得好的恰当的,哪些是翻得翻得不好的错误的,读了一点之后就去美亚买了英文版。


推薦閱讀:

如果對方是一個 Scala 愛好者,有什麼辦法說服他使用 Go?
Node.js、Scala、Clojure 等聲稱適合高並發的語言,分別具體適用於什麼情景,何種任務?
請問各位大神,spark的ML和MLLib兩個包區別和聯繫?!?
為什麼有些程序員看不起 PHP 這門語言?
scala case class 這時候該怎麼用?

TAG:Scala | 函数式编程 |