专访《Haskell函数式编程入门》作者张淞:浅谈Haskell的优点与启发

Posted InfoQ

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了专访《Haskell函数式编程入门》作者张淞:浅谈Haskell的优点与启发相关的知识,希望对你有一定的参考价值。

受访者简介

张淞,Haskell语言爱好者,著有《Haskell函数式编程入门》一书。目前就职于网易杭州研究院。



InfoQ:您好,可以简单做一下自我介绍吗?


张淞:我本名叫张淞 ,网上叫阅千人而惜知己,算是一个文艺屌丝吧。2012年从英国诺丁汉大学本科毕业,2013年从牛津大学研究生毕业,都是计算机科学专业。课程并没有特别明确的方向,但是由于偏爱函数式编程与编程语言一些,所以选课大多与之相关。2014年年初,因为母校宁波诺丁汉大学空缺一个临时的教职,于是牛津大学毕业后就先决定回国任教了,全职教授函数式编程这门课,所用的语言就是Haskell。目前供职于网易杭州研究院,现在的工作与数据分析相关。


InfoQ:从学校到公司应该有很多不同,可以分享一下这方面的感受么?


张淞:在学校工作时我没有研究压力,所以是比较自由的。在教函数式编程之前,这门课的课本我已经读了5遍,并且已经译成中文。书很薄,是由我在英国诺丁汉大学的老师Graham Hutton教授著的。后来在牛津又旁听了一遍这门课,当时还给有问题的同学答疑,所以回到宁波诺丁汉大学,教大二的学弟学妹们基本上是驾轻就熟的。教学任务也不是很大,一周大约有2小时的教学还有2小时的研讨课,课件、课本、练习、试卷的参考很多,也不用太花时间准备,所以比较轻松。有时间可以做自己喜欢的事,从SICP那本书上找一些题出给学生,读一些Haskell相关的论文。而在公司则不太一样,但是在网易杭州研究院,好处就是我们的工作不太会受到技术的限制,完全是由我们做什么、想怎么做决定的,不单调也不乏味,但只是感觉在公司的工作压力比较大,因为自己的工作关乎到其他同事的进度,但即便如此还是比较开心,因为还在做着自己喜欢的事。


InfoQ:Haskell吸引你的地方是?


张淞:严格地说我的第一语言是Java,教我学Haskell的人正是招我回去教书的那位老师。很坦诚地讲,Haskell在一开始并不吸引我,纯函数、没有变量让当时的我十分困惑并且有点抵触。后来考试完,在学校的图书馆里解了24点,发现用Haskell比同学的Java解法长度短了接近10倍,后来又解决了八皇后问题,也是比Java少了近10倍的代码;先不说效率,单纯在表达能力上,Haskell是不能与其他如Java一类的语言同日而语的。偶然间又在学校图书馆里发现了Real World Haskell,完全颠覆了我对Haskell肤浅的认识,才知道那薄薄的课本连Haskell的冰山一角都不算。


Haskell吸引我的地方主要是,强大的类型系统十分严谨,部分地方严谨到让人“发指”。这里可以举一个例子,3.14是小数,3.14e3等于3140,而3140可以当成数字来处理,因为它可以是整数,也可以是小数,所以应该归属于一个更为一般的类型类Num而不是Integral或者Fractional:


> :t 3.143.14 ::
Fractional a => aPrelude> :
t 3.14e33.14e3 :: Fractional a =>
aPrelude> :set -XNumDecimals
//开启语言扩展Prelude> :t 3.14e33.14e3
:: Num a => a


我没有看到任何语言注意到了这种类型上的微妙变化,Clojure里直接就是Double了。Haskell里数字类型与数字类型类的关系是相当严谨的,严谨到如果没有一定的理论背景根本不会清楚它背后这么设计的原因,Haskell里有很多不断颠覆我之前思想的设计。有这样细致入微的类型系统辅助可以保证很大一部分错误不会出现,因为根本写不出来不满足类型的代码,并且在我们的头脑并不清醒的时候编译器会始终帮助你保持理智。


另外,Haskell的基础API设计非常有条理,这也是一些语言比如Scala的scalaz、javascript的Prelude.ls、Ix,基本都是来基于Haskell Prelude的。Github上的CoffeeScript的coffee-mate与lazy.coffee,C++基于boost的prelude_CPP都或多或少受了Haskell的API设计的影响,你可以在Github上找到很多这样模仿Haskell Prelude的项目。


InfoQ:您感觉Haskell主要适合哪类项目?您在工作中使用多吗?


张淞:我并没有什么特别大的项目经验,只是在学校里做过几个玩具级别的编译器与解释器,另外还有一些其他小玩具,不能拿出见人的。但我能比较确定的是,用Haskell来编写其他语言的编译器与解释器肯定再合适不过了,整套流程我也比较清楚。恐怕最著名的例子可能就是唐凤的Perl 6实现——Pugs了,还有由Ulf Norell在博士期间用Haskell实现的依赖类型的编程语言——Agda,另外还有Haskell广泛使用的编译器GHC,从92年到现在已经20多年了,还是有非常好的可维护性并且在快速进化着,有很多教授与博士在这个平台上做研究,每次更新都有很多新的特性加入,一件事物有这种进化的能力其实是很可怕的,无论它刚问世的时候有什么缺陷。其实就我的所见所闻,Haskell从前端到高性能服务器、再到嵌入式开发、自动交易系统都有比较成功能例子,所以Haskell比较适合做什么更多的是由人来决定的。


我在工作中直接使用Haskell的机会并不多,但是我会使用Haskell做一些原型设计与网络接口测试。主要用的还是Haskell中的一些思想,比如代数类型、尽量消除变量的共享、尽可能多地使用纯函数等等,此外如果要在动态类型与静态类型语言中做选择,我会主观地倾向于后者。


InfoQ:在实际的业务开发中,选择编程语言会考虑哪些因素?


张淞:我工程经验并不是很多,主要是考虑要解决的问题与团队吧。最近解决的问题比较特殊,所以老大决定用了Clojure,因为需要用到一个很重要的库,只有Clojure的实现比较好,另外就是团队里的人多少都有一些函数式编程背景,所以最后决定使用了Clojure。


InfoQ:在国外会有不少实际的项目会应用到Haskell,比如近日InfoQ曾报道过《Facebook如何使用Haskell处理垃圾邮件》。就您所知,Haskell在国内的应用情况如何?



InfoQ:如果实际应用比较少,您感觉Haskell能给我们实际编程带来哪些启发?


张淞:我在前面大约提了几点,一个是Haskell核心的API的设计逻辑十分清楚,所以被很多语言争相模仿。无论你用什么语言,在设计API的时候照着Haskell中Functor、Applicative、Monad、Traversable、Foldable这些类型类来实现你的API,最后的逻辑条理都会非常清楚,基本不会看到眼花缭乱的设计模式满天飞,我在看其他语言的API的时候也会找它们在Haskell中的对应。在实践中很多事情是从零开始的,我一般是先会定义出全部我所需要的类型,然后把计算与程序运行的流程搞清楚,明确需要从哪些类型计算出哪些类型并把函数签名写下来,接下来开始实现他们,最后把它们组合起来得到最终完整的程序。


在10月15日~17日的QCon上海2015上,他将分享《Haskell中的函数与类型系统》:

Haskell中的主要概念其实都是围绕类型展开的,类型系统主要是为我们管理程序的抽象与保证程序的正确性而引入的。为了更好的复用代码,于是有了多态类型。某些类型有着共同的属性,于是Haskell引入了类型类来管理它们。有一些类型是需要接受一个或者多个类型参数的,为了保证这一环节不会出错,于是Haskell又引入了kind这一概念;同样出于复用代码的原因,Haskell又引入了kind多态。总之,抽象在一步一步加深,每加深一步就总结出更多公共的代码,为我们自动完成更多事情,而带来的问题就是会让人更加难以理解。所以了解Haskell的类型系统对于我们理解代码的复用、抽象非常有帮助。所以本次的演讲主要包括:


  • Haskell中的值

  • Haskell中的类型

  • Haskell中的类型类

  • Haskell中的类型的kind

  • 以上特性之应用


Haskell不仅仅是一门学术型的语言,而是一门非常适用于编写应用软件的工程型语言,其实相当多的思想是可以迁移到非函数式语言上的,但是对想要应用这些思想的人来说,在思维的转变上可能会有更长的路要走。主要的问题是,现在的人们习惯于他们已经熟悉的东西,需要学习如何让函数编程中的理论来指导实践编程,最大程度上减少重复,用更少的代码完成更多的工作。



更多大会讲师及专题前瞻

以上是关于专访《Haskell函数式编程入门》作者张淞:浅谈Haskell的优点与启发的主要内容,如果未能解决你的问题,请参考以下文章

CPU 原创 | 静态类型和函数式语言的趋势

haskell简明入门

为什么我更喜欢函数式编程

Haskell入门篇六:匿名函数定义

Haskell趣学指南

读 Learn You a Haskell for Great Good!