日记大全

日记大全 > 句子大全

Lisp:第一个函数式程序语言

句子大全 2008-07-14 15:56:52
相关推荐

LISP即列表处理语言(全名:List Processor),由约翰·麦卡锡在1960年左右创造的一种基于λ演算的函数式编程语言。LISP的祖先是1950年代Carnegie-Mellon大学的Newell、Shaw、Simon开发的IPL语言。

Lisp是第一个函数式程序语言,区别于C语言、Fortran等命令型程序语言和Java、C#、Objective-C等面向对象程序语言。由于历史的原因,Lisp长期以来被认为主要用于人工智能领域,但Lisp并不是只为人工智能而设计,而是一种通用的程序语言。

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

Lisp最初创建时受到阿隆佐·邱奇的lambda演算的影响,用来作为计算机程序实用的数学表达。因为是早期的高端编程语言之一,它很快成为人工智能研究中最受欢迎的编程语言。在计算机科学领域,Lisp开创了许多先驱概念,包括:树结构、自动存储器管理、动态类型、条件表达式、高端函数、递归、自主(self-hosting)编译器、读取﹣求值﹣输出循环(英语:Read-Eval-Print Loop,REPL)。

"LISP"名称源自“列表处理器”(英语:LISt Processor)的缩写。列表是Lisp的主要数据结构之一,Lisp编程代码也同样由列表组成。因此,Lisp程序可以把源代码当作数据结构进行操作,而使用其中的宏系统,开发人员可将自己定义的新语法或领域专用的语言,嵌入在Lisp编程中。

代码和数据的可互换性为Lisp提供了立即可识别的语法。所有的Lisp程序代码都写为S-表达式或以括号表示的列表。函数调用或语义形式也同样写成列表,首先是函数或操作符的名称,然后接着是一或多个参数:例如,取三个参数的函数f即为(f arg1 arg2 arg3)。

Lisp语言的主要现代版本包括Common Lisp, Scheme,Racket以及Clojure。1980年代盖伊·史提尔二世编写了Common Lisp试图进行标准化,这个标准被大多数解释器和编译器所接受。还有一种是编辑器Emacs所派生出来的Emacs Lisp(而Emacs正是用Lisp作为扩展语言进行功能扩展)非常流行,并创建了自己的标准。

Lisp的表达式是一个原子(atom)或列表(list),原子又包含符号(symbol)与数值(number);列表是由零个或多个表达式组成的序列,表达式之间用空格分隔开,放入一对括号中,如:

abc

()

(abc xyz)

(a b (c) d)

最后一个列表是由四个元素构成的,其中第三个元素本身也是一个列表,这种又称为嵌套列表(nested list)。

正如算数表达式1+1有值2一样,Lisp中的表达式也有值,如果表达式e得出值v,我们说e返回v。如果一个表达式是一个表,那么我们把表中的第一个元素叫做操作符,其余的元素叫做自变量。

Lisp的7个公理(基本操作符)

基本操作符1 quote

(quote x)返回x,我们简记为"x

(quote a)

上面的表达式的值是a。如果使用C语言或者Java语言的表达方式,可以说成:上面这段代码返回的值是a。

"a

这个表达式和上面的那个相同,值也是a。将quote写成 " 只是一种语法糖。

被quote起来的单一个元素会成为符号(symbol,例如"a)。符号是Lisp中的一个特别概念,他在代码中看起来是个字符串,但并不尽然,因为符号其实会被Lisp解释器直接指向某个存储器位置,所以当你比较"apple和"apple两个符号是否相同时,不需要像字符串一样一个个字符逐字比较,而是直接比较存储器位置,故速度较快(使用eq运算符来比较,如果使用equal运算符会变成逐字比较)。当你定义一个函数,或者定义一个变量时,他们的内容其实就是指向一个符号。

基本操作符2 atom

(atom x)当x是一个atom或者空的list时返回原子t,否则返回NIL。在Common Lisp中我们习惯用原子t表示真,而用空表()或NIL表示假。

> (atom "a)

t

> (atom "(a b c))

NIL

> (atom "())

现在我们有了第一个需要求出自变量值的操作符,让我们来看看quote操作符的作用——通过引用(quote)一个表,我们避免它被求值(eval)。一个未被引用的表达式作为自变量,atom将其视为代码,例如:

> (atom (atom "a))

这是因为(atom "a)的结果(t)被求出,并代入(atom (atom "a)),成为(atom t),而这个表达式的结果是t。

反之一个被引用的表仅仅被视为表

> (atom "(atom "a))

引用看上去有些奇怪,因为你很难在其它语言中找到类似的概念,但正是这一特征构成了Lisp最为与众不同的特点:代码和数据使用相同的结构来表示,只用quote来区分它们。

基本操作符3 eq

(eq x y)当x和y指向相同的对象的时候返回t,否则返回NIL,值得注意的是在Common Lisp中,原子对象在内存中只会有一份拷贝,所以(eq "a "a)返回t,例如:

>(eq "a "a)

>(eq "a "b)

> (eq "() "())

> (eq "(a b c) "(a b c))

基本操作符4 car

Contents of the Address part of Register number缩写

(car x)要求x是一个表,它返回x中的第一个元素,例如:

> (car "(a b))

a

基本操作符5 cdr

(cdr x)同样要求x是一个表,它返回x中除第一个元素之外的所有元素组成的表,例如:

> (cdr "(a b c))

(b c)

基本操作符6 cons

(cons x y)返回一个cons cell(x y),如果y不是一个list,将会以dotted pair形式展现这个cons cell,例如:

>(cons "a "b)

(a . b)

一个cons cell的第二项如果是另一个cons cell,就表示成表的形式,例如:

(cons "a (cons "b "c))

就表示成 (a b . c) 若一个cons cell第二项为空,就省略不写,例如:

(cons "a (cons "b ()))

表示为 (a b) 这样,多重的cons cell就构成了表:

> (cons "a (cons "b (cons "c ())))

(a b c)

基本操作符7 cond

(cond (p1 e1) ...(pn en))的求值规则如下。对“条件表达式p”依次求值直到有一个返回t.如果能找到这样的p表达式,相应的“结果表达式e”的值作为整个cond表达式的返回值。

> (cond ((eq "a "b) "first) ((atom "a) "second))

second

七个原始操作符中,除了quote与cond,其他五个原始操作符总会对其自变量求值。我们称这样的操作符为函数。

阅读剩余内容
网友评论
相关内容
拓展阅读
最近更新