图灵访谈之三:专访田春

10月23日,图灵社区就Lisp编程语言和《实用 Common Lisp编程》一书,采访了译者田春,以下为访谈内容:

人物简介:田春

Common Lisp 程序员, 毽球运动员, 跆拳道 2 级

网名“冰河”,Glority Software资深软件工程师,前网易杭州研究院高级开发工程师和系统管理员,资深Common Lisp程序员。

2001~2005年就读于浙江大学。2003年起开始学习Commom Lisp,精通Lisp史和各种实现,2007年起成为 LispWorks 付费用户,Common Lisp社区的网络专家,开源项目cl-net-snmp(SNMP协议库)的作者,usocket跨平台网络库的主要维护者,common-lisp.net站点管理员,水木社区(newsmth.net)函数型编程语言(FuncProgram)版主,美国Versata/Gensym公司技术顾问。

曾在2008年翻译了Paul Graham的On Lisp一书,在ILC 2009(国际Lisp会议)上发表学术论文,在《程序员》杂志上发表Common Lisp专题文章,并在网上撰写过大量相关的技术文章。

图灵社区:你好,田春,可能大家更熟悉的还是你的网名“冰河”,先向社区的读者介绍一下自己,好吗?

田春:大家好。首先,关于敝人的网名,其实是自小学起就在使用的笔名或昵称,只是一个名字而已。但需要解释的是,敝人跟传说中的冰河木马没有任何关系,重名纯属巧合。

我从小学五年级开始学习计算机,早年在NOI信息学竞赛上只有一点小成绩,初高中阶段沉迷游戏和DOS/Windows编程,学习成绩很一般,高考时超常发挥才有幸考入浙大一个非计算机专业。 大学期间自学了包括Linux和Lisp在内的多种计算机知识,毕业后凭借在校期间Linux方面的声望进入网易公司从事系统管理,工作期间继续学习Common Lisp,在该领域写过开源项目、发表过国际会议论文、翻译过经典英文教材,最后因机缘巧合接触到国外的古老商业Lisp软件,经过两年多的努力,目前以维护该软件为生。

图灵社区:你的经历真是跟Lisp是息息相关啊,但很多人对Lisp只有一个模糊的概念:这是一种中古语言,能否结合你自己的经历谈谈Lisp?

田春:在我计算机生涯的前十年,其实完全没有想过将来会以此谋生。我选择计算机领域的具体学习方向几乎完全是兴趣导向的。早期的时候,信息相对封闭,我和当时其他同行一样走的是从DOS到Windows,从BASIC到C或Pascal再到Visual Studio系列,这样一个循规蹈矩的学习路线。后来到杭州读大学,不久就开始学习Linux和Lisp。

我的Lisp经历可以分为N个阶段:

1) 人工智能编程语言阶段——小学五年级和六年级。那时有一本书,叫做《计算机应用指南》,里面讲述了1994年时整个计算机领域的状况,其中“人工智能与专家系统”那章里着重强调了Lisp和Prolog这两种AI语言的应用。这是我最早的Lisp印象。

2) GNU 和Emacs阶段——大学第一年。GNU工程的创始人R. Stallman早独立完成了两大自由软件:GCC和Emacs,后者使用一种Emacs Lisp语言来扩展Emacs环境。Stallman本身也是Lisp黑客,在Lisp机上写过真正的Lisp程序,还参与过Common Lisp语言第一版(CLTL1)的标准制订工作。按理说所有学习Linux的人都多少会受到一些Lisp方面的熏陶,遗憾的是,最终多数人只是停留在Emacs和elisp层面上,我算是少数顺着这条Lisp道路一直走向终极(Common Lisp)的那些人。

3) Scheme阶段——大学的第三年。通过 SICP 一书和 MIT OpenCourseWare 的配套视频来学习,那个时候广泛接触了Linux系统自带的各种Scheme软件包,在学习计算机一般理论的同时学习Scheme语言。我逐渐发现Scheme语言本身太简单了,具体的实现又非常多,互相之间区别很大。很多人最终停留在Scheme阶段,其中少数有能力的人又自己创造了许多新的Scheme实现。但我没有停下来,继续向前走。

4) Common Lisp 阶段I——大学第三年晚期和第四年。学习 Debian 系统自带的 onlisp 和* Common Lisp the Language *电子书,然后用 Debian 自带的 CMU Common Lisp,Steel Bank Common Lisp,GNU Common Lisp以及GNU CLISP等环境来进行Common Lisp编程实践。

Debian里还有几个很大的Common Lisp写出的软件,包括Maxima和Axiom两种数学符号计算系统。CMU Common Lisp (cmucl) 的软件包文档里有The Evolution of Lisp这篇著名的论文。我读完以后,顺藤摸瓜通过学校内网的ACM Digital Library等论文渠道,把关于Lisp语言发展史的关键论文几乎全看了一遍。不过,这个时候还没写出一个像样的Common Lisp程序,完全是在学习。

5) Common Lisp 阶段II——主要是发起自己的开源项目(cl-net-snmp),试图翻译各种Lisp资料——最主要的就是On Lisp一书。我认为这是一个领域的新手通常会做的两件事。

6) Common Lisp阶段III——参与维护别人发起的开源项目(usocket、cl-xml、cl-http、cffi 等),以及试图了解和改进各种Common Lisp 平台本身的源代码。捎带着参与Lisp相关的国际会议,把自己的成果整理成论文,以便跟其他同行建立联系,走向领域前沿。

我现在处在一个新的阶段,并且也走向了Lisp领域一条冷门的岔路上:维护前人留下的古老商业Lisp软件。我不认为这是一条终极道路,相反这是一条歧途,但我必须去做,因为如果我不做的话,这些有价值的东西就可能失传。我现在的工作与其说是为了谋生和个人兴趣,还不如说是像一个历史学家一样,在努力地行使保护历史文物的职责。Lisp领域可谓是浩如烟海,没有其他任何语言具有像Lisp这样的深度和广度,也没有哪个语言的程序员可以像Lisp程序员那样热爱自己的语言。这是我的观点,但它的真正内涵需要人们自己去体会。

图灵社区:关于编程语言的学习,你有一个很有意思的观点——C和Lisp是编程语言的两个极端。可否就此谈谈,并对如何学习编程语言提供一些建议?

田春:这实际是 Paul Graham 在The roots of Lisp(Lisp之根源)这篇文章中提出的观点。该文第二段里是这样写的:

“我认为目前为止只有两种真正干净利落, 始终如一的编程模式:C语言模式和Lisp语言模式。此二者就像两座高地,在它们中间是尤如沼泽的低地。随着计算机变得越来越强大,新开发的语言一直在坚定地趋向于Lisp模式。二十年来,开发新编程语言的一个流行的秘决是,取C语言的计算模式,逐渐地往上加Lisp模式的特性,例如运行时类型和无用单元收集。”

我是在同意 Paul Graham 的上述观点的基础上,做出了“C和Lisp是编程语言的两个极端”这一评价的。但我的依据除了两种语言的语法风格迥异以外,还考虑了C程序和Lisp程序截然不同的运行方式:C程序总是一些零零散散的独立可执行文件,由操作系统把它们拼接在一起;而Lisp程序本质上是对Lisp环境和Lisp语言本身的扩展,Lisp环境就像一个虚拟机一样,行使着操作系统的职责,把其中加载的所有Lisp代码运行起来(Emacs又何尝不是如此呢)。纵观其他所有语言,我看不出还有本质上的第三种方式了。

图灵社区:我们知道Common Lisp是Lisp的一门方言,对这门方言的实际应用和未来前景,你有什么看法呢?

田春: Common Lisp 是 Lisp 语言家族中唯一具有工业强度的大型语言,它本身就是为了把之前所有真正用来一般性软件的 Lisp 语言统一起来,尽量兼容它们并消除不一致的地方,最后得到一个完美的集大成体。这个目标事实上确实实现了。1991年,Common Lisp发布第一版,至今所有代码几乎可以不经任何修改,就运行在目前还在流行的至少10种不同的Common Lisp环境上,整整二十年来Lisp程序员的成果一直可以正常运行,这对Lisp程序员无疑是一种巨大的鼓励。相比之下,其他的语言要么消失了,要么已被改得面目全非。

我的看法是,一个追求卓越的程序员应该广泛尝试多种语言,但如何他真的这样做了,他一定会在遇到Common Lisp时停下来,因为他发现这门语言是最强的,也是最美的,并且学习过程也是最艰难的,艰难到以至于学成之后,再没有精力也没有必要去学其他语言了。然后他就会想尽办法让一切编程事务都用Common Lisp来做,最后会奇迹般地发现Common Lisp什么都可以干,而且没有哪个领域是干不了的,甚至于没有哪个领域是尚未有Lisp程序员踏足的。

至于前景,就像我在《实用 Common Lisp编程》一书译者序里表达的:一门语言能安全地存活50年,那么它就一定可以存活100年。人生宝贵,如果希望自己的劳动成果长久流传于世,那么选用Common Lisp来表达自己的思想是最稳妥的。

图灵社区:《实用Common Lisp编程》的作者,强调了Lisp的“可编程性”和“适合探索性编程”。就这本书,他是如何体现这些特色的?这些带来怎样的阅读体验呢?

田春:主要体现在贯穿于书中的实践性章节里。在很多其他语言的类似实践性章节里,可能是把程序的最终版本逐个部分地向读者做解释,比如这个函数将会完成哪些功能,那个类是做什么用的,诸如此类。但在学习者把所有代码输入电脑之前,程序是几乎跑不起来的。而在《实用 Common Lisp编程》一书里,作者借助Lisp语言本身的强大优势,采用真正的循序渐进教学法:每一个函数,都从直接可以运行并完成实际功能的简单版本开始,然后再根据逐渐复杂的需求被不断改写;或者单个函数规模变大以后,再添加新的子函数,诸如此类。这样能够确保学习者每次都能取得阶段性成果,同时演示了Lisp程序员们真正写程序时,是如何从零开始,边设计边施工,最后一路积累千上万行代码的。

我自己也写过超过1万行代码规模的cl-net-snmp项目——一个完整的SNMP协议实现。在这个项目里,我甚至做出了MIB编译器,把MIB定义转译成Lisp,然后要么解释要么编译加载。这个项目就是从零开始,先解决ASN.1各种基本数据类型的BER编解码,然后封装SNMP数据包,再做MIB的语法解析,直到整个服务器和客户端都正常跑起来。Common Lisp开源社区的同行对我的成果极为称赞,虽然我的代码质量和程序效率还不行,但人们普遍惊讶我可以用Lisp,将一个看似简单的网络协议以最复杂也最贴近Lisp的方式成功实现。学完这本书的实践部分,就可以掌握编写Lisp程序的正统思路。然后无论多么复杂的程序,都可以用同样的思路逐渐写出来。

图灵社区:能不能向有志于学习Common Lisp的初学者,介绍一些网络资源呢?

田春:所有最重要的网络资源,都写在这本书的最后一章里。但我认为对于初学者来说,看书是最重要的。Common Lisp the Language(CLTL2) 是最重要的 Common Lisp 语言大全。说起来, 《实用Common Lisp编程》一书只涵盖整个语言不到一半的特性。要想写出最专业的代码,必须了解并且灵活组合运用这门语言所给予程序员的所有东西。因此CLTL2是一定要看完的,遗憾的是仔细看完这本书至少需要半年。

无论如何,我不推荐人们过早地去参与各种线上讨论,因为Lisp社区对新手并不友好,国外的社区尤其是这样,贸然去问各种无聊的问题只会自取其辱。

图灵社区:跟你合作本书的过程中,图灵的编辑都获益良多。在这次的合作之后,你对技术图书的出版,又有哪些看法和建议呢?

田春:这本书得以顺利出版,还是要感谢图灵的编辑们的。尽管这本书8月份的时候离出版还遥遥无期,我当时采取了一个手段威胁你们(笑)。不过,有几点我还是不太满意的:一是排版用Word太不专业,推荐用LaTex排版;二是这本书的最后没有索引,其实索引对这本书比较重要,因为所有粗体的字都是Common Lisp的关键字,写代码的人想用某个语句的时候,可以通过索引来查询;三是出版周期还是太长。

至于建议,一是希望图灵的书今后能保留索引,方便读者查阅;二是应在翻译合同中加入出版时间的约定,规定交稿后多长时间出版;三是希望图灵能引进On Lisp的版权出版翻译版,我可以提供译稿供出版使用。

图灵社区:感谢田春接受图灵社区的采访,与大家分享自己学习Lisp的经历,以及对Lisp的看法。


更多精彩,加入图灵访谈微信!

图灵访谈系列之七:吴朱华谈云计算和创业