LISP

title: 历史.
title: 20世纪.
content: 1955年至1956年间,资讯处理语言被创造出来,用于人工智能处理(早期的基于符号处理的人工智能领域,以图灵测试为目标)。此领域中有研究者持有观点:“符号演算系统可以衍生出智能。”。它首先使用了列表(抽象数据类型)与递归。  1958年,约翰·麦卡锡在麻省理工学院发明了Lisp程序语言,采用了资讯处理语言的特征。1960年,他在《ACM通讯》发表论文,名为《递回函数的符号表达式以及由机器运算的方式,第一部》(Recursive Functions of Symbolic Expressions and Their Computation by Machine, Part I)。在这篇论文中阐述了只要透过一些简单的运算子,以及用于函数的记号,就可以建立一个具图灵完备性语言,可用于算法中。  麦卡锡最初使用M-表达式写程序码,之后再转成S-表达式,举例来说M-表达式的语法,codice_2,等同于S-表达式的。然而由于S-表达式具备同像性的特性(homoiconic,即程序与资料由同样的结构储存),实际应用中一般只使用S-表达式。此外他也借用了资讯处理语言中的许多概念。  约翰·麦卡锡的学生史帝芬·罗素在阅读完此论文后,认为Lisp编程语言当中的codice_3函数可以用机器码来实做。他在IBM 704机器上,写出了第一个Lisp解释器。1962年,蒂姆·哈特(Tim Hart)与麦克·莱文(Mike Levin)在麻省理工学院以Lisp编程语言,实做出第一个完整的Lisp编译器。这两人在笔记中使用的语法比麦卡锡早期的代码更接近现代Lisp风格。  然而使用20世纪70年代当时的编译器技术和硬件,要实现Lisp还是困难的挑战。由研究生丹尼尔·爱德华兹所开发的垃圾收集程序,使得在通用计算机上运行Lisp变得实用,但效率仍然是一个问题。这导致了Lisp专用机器的创建:用于运行Lisp环境和程序的专用硬件。之后计算机硬件和编译器技术的发展迅速,使得昂贵的Lisp专用机器过时。
title: 公元2000年迄今.
content: 在20世纪90年代衰退之后,Lisp最近十年来因一些关注而逐渐复苏。大多数新活动都集中在Common Lisp,Clojure,Racket,Scheme和Emacs Lisp的实作上,包括开发新的跨平台函式库和应用。当其他人认为Lisp已经是过时陈旧的,如保罗·格雷厄姆和埃里克·雷蒙等人继续出版有关于Lisp编程的著作,一些新的开发人员受到这些作者启发,经常将Lisp这种语言描述为令人大开眼界的经验,并声称在本质上比较其它编程语言更有生产效率。这种意识的提高可对比于,如同Lisp在90年代中期“人工智能冬季”的短暂增长。  Dan Weinreb在他的调查中,列出了11个积极维护中的Common Lisp实作。Scieneer Common Lisp是一个新的实作商业化产品,由CMUCL于2002年首次发布。  开源社群建立了新的支援基础:CLiki是个收集Common Lisp相关资讯的维基,Common Lisp目录列出了资源,#lisp是一个受欢迎的IRC频道,可以共享和注释代码片段(在lisppaste的支持下,一个用Lisp编写的IRC机器人),Planet Lisp收集了各种 Lisp相关博客的内容,LispForum用户讨论Lisp主题,Lispjobs是个公布职缺机会的服务,还有一个Weekly Lisp News提供每周新闻。Common-lisp.net是开源专案的托管站点。Quicklisp则是含括了许多函式库的装载管理器。  Lisp50@OOPSLA庆祝了Lisp的50周年(1958-2008)。在波士顿,温哥华和汉堡有定期的当地用户会议。其他活动包括欧洲共同Lisp会议,欧洲Lisp专题讨论会和国际Lisp研讨会。Scheme社群积极维护了二十多个实作。在过去几年中已开发了数个有意义的新实作(Chicken,Gambit,Gauche,Ikarus,Larceny,Ypsilon),Scheme社群广泛接纳了R5RS语言标准。Scheme需求实作过程建立了很多预备标准函式库和Scheme扩展功能。各种 Scheme实作的用户社群持续地增长。  一个新的语言标准化过程于2003年开始,并在2007年产生了R6RS标准,而使用Scheme介绍计算机科学课程的学校似乎有所减少。麻省理工学院的计算机科学入门课程,已经不再使用Scheme。  有几种新的Lisp方言:Arc,Hy,Nu,Clojure,Liskell,LFE(Lisp Flavored Erlang)和Racket。
title: 基本介绍.
content: Lisp是第一个函数式程序语言,区别于C语言、Fortran等命令型程序语言和Java、C#、Objective-C等面向对象程序语言。由于历史的原因,Lisp长期以来被认为主要用于人工智能领域,但Lisp并不是只为人工智能而设计,而是一种通用的程序语言。  Lisp的表达式是一个原子(atom)或列表(list),原子又包含符号(symbol)与数值(number);列表是由零个或多个表达式组成的序列,表达式之间用空格分隔开,放入一对括号中,如:  最后一个列表是由四个元素构成的,其中第三个元素本身也是一个列表,这种又称为嵌套列表(nested list)。  正如算数表达式1+1有值2一样,Lisp中的表达式也有值,如果表达式codice_4得出值codice_5,我们说codice_4返回codice_5。如果一个表达式是一个表,那么我们把表中的第一个元素叫做操作符,其余的元素叫做自变量。
title: Lisp的7个公理(基本操作符).
title: 基本操作符1 quote.
content: codice_8返回x,我们简记为'x 上面的表达式的值是a。如果使用C语言或者Java语言的表达方式,可以说成:上面这段代码返回的值是a。  这个表达式和上面的那个相同,值也是a。将quote写成'只是一种语法糖。  被quote起来的单一个元素会成为符号(symbol,例如'a)。符号是Lisp中的一个特别概念,他在程序码中看起来是个字串,但并不尽然,因为符号其实会被Lisp解释器直接指向某个内存位置,所以当你比较'apple和'apple两个符号是否相同时,不需要像字串一样一个个字符逐字比较,而是直接比较内存位置,故速度较快(使用eq运算子来比较,如果使用equal运算子会变成逐字比较)。当你定义一个函数,或者定义一个变量时,他们的内容其实就是指向一个符号。
title: 基本操作符2 atom.
content: (atom x)当x是一个atom或者空的list时返回原子codice_9,否则返回NIL。在Common Lisp中我们习惯用原子codice_9表示真,而用空表codice_11或codice_12表示假。  现在我们有了第一个需要求出自变量值的操作符,让我们来看看quote操作符的作用——通过引用(quote)一个表,我们避免它被求值(eval)。一个未被引用的表达式作为自变量,atom将其视为代码,例如:  这是因为codice_13的结果(codice_9)被求出,并代入codice_15,成为codice_16,而这个表达式的结果是t。  反之一个被引用的表仅仅被视为表  引用看上去有些奇怪,因为你很难在其它语言中找到类似的概念,但正是这一特征构成了Lisp最为与众不同的特点:代码和数据使用相同的结构来表示,只用quote来区分它们。
title: 基本操作符3 eq.
content: (eq x y)当x和y指向相同的对象的时候返回t,否则返回NIL,值得注意的是在Common Lisp中,原子对象在内存中只会有一份拷贝,所以codice_17返回t,例如:
title: 基本操作符4 car.
content: Contents of the Address part of Register number缩写  (car x)要求x是一个表,它返回x中的第一个元素,例如:
title: 基本操作符5 cdr.
content: (cdr x)同样要求x是一个表,它返回x中除第一个元素之外的所有元素组成的表,例如:
title: 基本操作符6 cons.
content: (cons x y)返回一个cons cell(x y),如果y不是一个list,将会以dotted pair形式展现这个cons cell,例如:  一个cons cell的第二项如果是另一个cons cell,就表示成表的形式,例如:  就表示成 (a b. c) 若一个cons cell第二项为空,就省略不写,例如:  表示为 (a b) 这样,多重的cons cell就构成了表:
title: 基本操作符7 cond.
content: (cond (p e)...(p e))的求值规则如下。对“条件表达式p”依次求值直到有一个返回t.如果能找到这样的p表达式,相应的“结果表达式e”的值作为整个cond表达式的返回值。
title: 函数.
content: 七个原始操作符中,除了quote与cond,其他五个原始操作符总会对其自变量求值。我们称这样的操作符为函数。
title: Lisp的宏.
content: Lisp的语法结构使数据与程序只是一线之隔(有quote就是数据,没quote就是程序)。由于Lisp这种「数据即程序、程序即数据」的概念,使Lisp的宏(Macro)变得非常有弹性:你可以定义宏,指定它应该被编译器翻译(宏展开)成什么程序,程序和数据都可以灵活地互相转换,最后展开的代码会成为整个程序的一部分。宏的实现非常倚重quote来达成。当你定义了一个宏,宏被quote的部分会先被编译器unquote,而没有quote、或已经被unquote的部分,则会先被求值。最终编译器生成的整个程序代码才是最后执行时的代码。以下以广泛使用的Emacs Lisp为范例(以下范例亦相容Common Lisp),解释最基本的Lisp宏。  想要建立一个list并赋予给fruit这个变量时不能这样做,因为这个list没有被quote过,会被编译器视为「程序」执行(会把"apple"这个字符串当成函数解释),而不是「数据」,因而产生错误:  但这样就正确了:  前面有提到使用'符号这个语法糖能够代替quote,但还有另外一种符号是`,意义基本上与'相同,但被`包起来的部分可以再用来unquote;而'没有这种能力。  也就是说被`给quote起来的部分是资料,但使用逗号“,”来unquote,令被quote的数据变回程序。(注意quote只有一个arg,所以arg要用list包起来)
title: 简易宏范例.
content: 这里定义一个宏叫做codice_18,这个宏可以方便地定义更多以codice_18为开头的新函数:

Summary: Lisp(历史上拼写为LISP)是具有悠久历史的计算机编程语言家族,有独特和完全括号的前缀符号表示法。起源于公元1958年,是现今第二悠久而仍广泛使用的高阶编程语言。只有FORTRAN编程语言比它更早一年。Lisp编程语族已经演变出许多种方言。现代最著名的通用编程语种是Clojure、Common Lisp和Scheme。

Lisp (programming language): Lisp (historically LISP) is a family of programming languages with a long history and a distinctive, fully parenthesized prefix notation. Originally specified in 1958, Lisp is the second-oldest high-level programming language in widespread use today. Only Fortran is older, by one year. Lisp has changed since its early days, and many dialects have existed over its history. Today, the best-known general-purpose Lisp dialects are Racket, Common Lisp, Scheme and Clojure.