为蛇足者,终亡其酒
——《战国策》
这个系列终于写完,很是费了我不少力气,因为我从小语文就一直不太好,有时很难表达清楚自己的意思。这次算是自己撵着自己这只鸭子上架吧。
Lisp的历史十分悠久,据说仅次于Fortran,算得上是第二古老的语言。对于Fortran,语言学家给予的负面评价远比正面评价多,甚至在很多场合被作为程序设计语言的反面教材;但是Lisp则刚好相反,它一直被人们作为一个优秀作品的例子被大加赞扬,这些人中包括著名的计算机科学家,Smalltalk的发明人——Alan Kay。
有一个传言,据说McCarthy当时想把这门语言的语法设计往后拖一拖,等到他把一些有趣的事做完之后,再回过头来给这门给予Lambda演算理论的语言加上一些数学家们熟悉的语法,可是他的一个学生发现,在一个还没有定义正式语法的抽象语法上中写程序,感觉非常好,于是McCarthy干脆就决定不定义Lisp的语法。直到如今,Lisp的“语法”定义中值得一提的规则似乎只有一条“括号要配对”,其它的都是“语义”上的规范。
这样做当然不是没有代价的,很快Lisp就出现了第一个分支Scheme。这个语言由Guy Steele, Jr.和他的老师Gerald Sussman设计。这两位最开始的工作是改进Lisp,他们共同把Lisp由Dynamic scope变成了Lexical scope。今天几乎大家熟悉的所有语言都是Lexical scope。后来他们共同把Continuation这个概念引入了Lisp,于是一门新语言就这样诞生。
随后,Sussman把Lexical scope和Scheme中的一些其它概念都引入了Lisp,并由此确立了Common Lisp的标准,Sussman本人也一直是Common Lisp的主力。
作为一门最早出现的FP语言,Lisp当然有它的缺点,其中最为人诟病的恐怕就是括号了,所以随后出现的许多FP语言都试图使用另外的语法来清晰的描述程序,这其中最著名的当属Haskell(也许还有Caml?),Haskell是一门“纯正”的FP语言,在Haskell中,变量不能赋值,没有循环,甚至没有程序流程,一切都是函数。
(注:我个人认为,想要领会FP的精髓,用Haskell入门似乎更合适)
近年来,随着FP的进一步流行,许多命令式语言当中也逐步加入了FP的成分,典型如C++中的“functor”,如果你用过STL或者Boost,你会发现利用functor可以完成很多不可思议的功能。就我个人的经验,functor最密集的应用是在Boost.Spirit库中,它可以让你用一大堆Parse/Match Functor构造一个复杂的语法分析器。
熟悉一门函数式语言,用心体会它的妙用。在你转变思维方式后,你会发现即便是原来你熟悉的命令式语言也能发挥出更大的威力。
参考文献:
“Recursive Functions of Symbolic Expressions and Their Computation by Machine, Part1.” Communication of the ACM 3:4, April 1960. “The Art of the Interpreter, or the Modularity Complex (Parts Zero, One, and Two)”, Guy Lewis Steele, Jr. and Gerald Jay Sussman, MIT AL Lab Memo 453, May 1978. “Lisp 1.5 Programmer's Manual”, John McCarthy, Paul W. Abrahams, Daniel J. Edwards, Timothy P. Hart, Michael I. Levin. 在线资源:
可免费获取的Windows版的Common Lisp版本似乎不多,能想到的只有一个CLISP,网址在:
http://clisp.cons.org 可用于Linux的Common Lisp我知道的有CMUCL和SBCL,网址分别是:
CMUCL: http://www.cons.org/cmucl/
SBCL: http://sbcl.sourceforge.net
另外,一个被广泛应用于Gnome中的Scheme实现——guile也包含在绝大多数Linux发行版里。 对Haskell有兴趣的朋友可以去http://www.haskell.org 找到很多关于Haskell的信息,同时,在http://www.haskell.org/hugs/ 你可以下载到Windows版和Linux/Unix版的Haskell解释器——Hugs98。 Lisp入门(一)
等着我,不要走开,还有更精彩的内容哦…………
注1:Lisp在其几十年历史中有相当大的变化,本文中所包含的程序遵照的是《Lisp 1.5 Programmer's Manual》中的标准,很多程序并不能在Common Lisp中使用,需要做一些改动,但是相信我,这些改动都是很小的。
注2:很多书,甚至包括很多教科书,都把Lisp称之为一种“解释性语言”,可是自从第一个Lisp编译器MacLisp出现到现在已经有三十多年了,所以,不要相信那些书上的废话。