我为什么学习Haskell?
即使我的专业不是计算机,我也从来没有考虑过将来要用写代码去养家糊口,然而编程却一直是我醉心的事。从我第一次看见电脑至多年以后终于可以自由的学习它,我渴望掌握它、控制它,渴望自己的思维在它的身上跳跃。
我学的第一门语言是C和C++,C是学校的必修课,而C++却是我自己想要多掌握一些东西。怎么样写成一个程序?对于每一个首次去学习编程的人,这个问题多少能迷惑他们。是把源代码的扩展名改为exe吗?刚入编程这条道的人开始往往是非常艰辛,这种艰辛感直至多年以后仍会历历在目。我永远也忘不了刚学C时写八皇后程序的艰难,现在看当时那些冗长繁琐丑陋的代码,我会笑那时的“执着”。其实我觉得编程是一件当你没有越过那道坎就会难得不得了,一旦当你越过了往后就一马平川的事情。只是一学期的课程往往不够让普通的学生越过这道坎,所以大部分的学生即使修了这门课也依然不知所云。流行在清华的段子,女同学甩了她的前男友找了另一个男生,因为这个男生帮她完成了C的大作业。哈哈,其实你看,会编程是多么的有用啊。
然后我陆继学了Java、C#、Fortran、Python,学Java和Fortran完全是课程需要,我自始自终都没有真正应用过它们。学C#是当时看到看到关于C#(.NET战略)的宣传和书籍铺天盖地,而且正好我参与了一个项目要求使用.NET来开发,所以我就理所当然地放弃了当时正准备认真学下去的MFC,投入了C#的阵营。学C#和用C#一直持续了近两年,我想总共也写了几万行代码吧。那时候C#就是我最拿得出手的语言,在我心里,它是如此强大与完美。
后来,我开始接触新的三维渲染程序项目,C++&OpenGL&MFC,开始我还雄心勃勃地想,这个程序用C#来写多好多快啊~后来,后来我终于知道我的狭隘了。毫无疑问就开发速度来说C#远胜过C++,然而一旦显著的关注程序的性能,C++的优势就出来了。于是,我又开始转回去重新学C++。就这样,我与C#分手,此后,我几乎没有再用过它,而它的版本号已经不断升级,从2.0已经升到了4.0+。现在想来,像C#这样的语言可以了解它、掌握它,用它来做项目,然后若说以精通它作为自己的核心竞争力,我总觉得有些惴惴不安。当你了解一个语言是由一个公司创造与维护,局限于一个平台,为了一个公司的发展而服务,你不知道这个语言的明天会是怎样。
C++是我后来最主要用的语言,开始是项目需要,而后,变成了内心的喜爱。我喜爱它,觉得它像是武林中至上的内功心法,虽然非常难学,但是愈深入,功力就愈深厚。因为它最大的开放了底层的细节,给了编程者最大的可控制性,所以语言本身语法的细节就很多,语法背后的东西也很多,学习曲线也就很长很长。之前有人让我推荐学C++的书,我一般只说一本《C++ Primer》,如果能看懂这本书的90%以上,我想已经足够一般的应用了。如果再向深,那么这个书单是:《STL源码剖析》,《Effective C++》,《More Effective C++》,《Essential C++》,《Inside the C++ Object Model》,《Thinking in C++》,Boost,《Imperfect C++》,《The Design and Evolution of C++》。如果要做界面,Qt或者MFC你总得学一个吧。然后,都到这份上了,其它方面也得跟上吧,《深入理解计算机系统》,正则表达式,XML,设计模式,《算法导论》,UML,并行计算……真心太长了。
我忘了是什么时候看到了Eric的如何成为一个黑客,那个时候我开始想要听从他的建议,学一种传统语言(静态,强类型,高效率),纯面向对象语言,脚本语言,函数式语言(注:其实这不是他的原话,我稍微篡改了一下:) )。我想就是那个时候我开始好好学习Python,并且想有时间的时候要学一个函数式语言。Python也是一个我非常喜欢的语言。它的简单、实用而强大、流行(意味着有问题时总是能在Google上找到答案)。写Python代码问题一件很愉快的事,甚至在理解了它的基本的语法后,我都是一边解决问题一边学Python。也许这是为什么Eric推荐Python作为初学编程者的第一门语言吧。但我觉得如果只有学过Python,没有学过C或者C++你也许难以真正理解GC的那些事。还有就是《代码之美》里有一章关于Python的高效字典对于理解Python也很不错。
11年5月的时候,我买了两本书,一本是The Real World Haskell,另一本是Programming Erlang(话说我真是爱极了OREILLY的书)。至于为什么我准备学习这两门语言,我也忘了,总之这是我调研的结果吧。买了书之后,后来又因为还有其他更重要的事,这事又落下了。一直到12过完年,这次终于下定决心好好学好Haskell。要说原因,最主要的还真是完成自己学一门函数式语言的愿望,完善自己的编程大框架。其实当学习个东西却找不到拿这个去干什么的时候,这才是最艰难的。无数次我纠结于那些全新的概念与无法领悟的难点,我都想,我费了这么劲来学这个能够用来干什么吗。好吧,我告诉自己,05年Jobs在斯坦福的演讲,跟随你的内心去做你喜欢的事,重要的是你要相信有一天这些东西都可以被串起来。
当我跟着书往下走的时候,学到monad就卡住了。事实上,网上关于Monad多难多难学的各种说法首先就把我吓住了。这时候我又开始用Learn You A Haskell这本网上教程来重新开始学习,这样下去,似乎就是某一天,忽然一切都开阔了,当我用心去看的时候我都可以知道那是在说什么。就像是教程的介绍部分所说的,"I failed to learn Haskell approximately 2 times before finally grasping it because it all just seemed too weird to me and I didn't get it. But then once it just "clicked" and after getting over that initial hurdle, it was pretty much smooth sailing. I guess what I'm trying to say is: Haskell is great and if you're interested in programming you should really learn it even if it seems weird at first. Learning Haskell is much like learning to program for the first time — it's fun! It forces you to think differently, which brings us to the next section."。
那么,Haskell到底带给了我什么?我想说有三点。第一,它给了我一种前所未有的思维方式。对于像map,filter,fold这些高阶函数的使用与熟悉,让我理解了这些函数所对应是广泛的对数据处理的相同模式的归纳,而这种思想即使是用其它语言来编程,来能够让我写出更加简洁紧促的代码。在学Haskell之前,我就从来没有理解过Python语言对函数式编程的支持。第二,它的惰性让我们可以写出其它语言很难做到的事。比如求第i个素数,在Haskell我是这样写的,primeAt i=(filter isPrime [2..])!!(i-1)(注:这是一个比较低效的求素数列的方法),其中isPrime是一个判断一个整数是否是素数的函数。因为Haskell的惰性,我们才得以写下像[2..]这样的无穷数组。第三,Haskell对数学的支持。当我用Haskell来Project Euler上面的题目的时候,感觉非常流畅,真是相当的棒。Haskell是由一群数学家创造的,毫无疑问对数学家是相当关照的啊。
前阵子有另外一些事,学Haskell的事又停下了,但我想最终我会学好Haskell的,阿门。