linux lisp,LISP基础

部分摘录于《ANSI COMMON LISP》、《LISP语言(陈光喜)》

变量与赋值

let来完成局部变量的定义,形式如下:

(let ((var 1 exp1) (var2 exp2) ... (varn expn)) exps)

其中,(vari expi)表示对于变量名vari,该变量的初始值为表达式expi的值。let语句中的exps部分为表达式集合,完成所需要的处理。整个let语句的返回值为语句体中的最后一条语句的值。

函数的表示

函数表示为(lambda (p1...pn) e),其中(p1...pn)是原子,也叫参数,e是表达式。

如果一个表达式的第一个元素形式如上所示:

((lambda (p1...pn) e) a1...an)

则称为函数调用。它的计算过程如下:每个表达式ai先求值,然后e在求值。在e的求值过程中,每个出现在e中的pi值是对应相应的ai在最近一次的函数调用中的值。

有另外一种函数极好使得函数能提及它自身,这样我们能更方便地定义递归函数。

(label f (lambda (p1...pn) e))

记号f表示一个像(lambda (p1...pn) e)那样的函数,这样,任何出现在e中的f将求值为此label表达式,就像f是此函数的参数。

假设定义函数(subst-new x y z),它使用表达式x,原子y和表z作为参数,返回一个像z那样的表,不过z中出现的y需要被x代替。

(label subst-new (lambda (x y z)

(cond ((atom z)

(cond ((eq z y) x)

('t z)))

('t (cons (subst-new x y (car z))

(subst-new x y (cdr z)))))))

我们简记f=(label f (lambda (p1...pn) e))为:

(defun f (p1...pn) e)

于是:

(defun subst-new (x y z)

(cond ((atom z)

(cond ((eq z y) x)

('t z)))

('t (cons (subst-new x y (car z))

(subst-new x y (cdr z))))))

变量

let是CommonLisp里最常用的操作符之一,它让你引入新的局部变量:

> (let ((x 1) (y 2))

(+ x y))

3

这些变量只有在let体内有效。变量和值的列表后面是一组表达式,它们被依此求值。

通过传给defparameter一个符号和一个值,可以构造全局变量:

> (defparameter *glob* 99)

*GLOB*

习惯上全局变量的名字以星号开始和结束。

可以使用defconstant定义全局变量:

(defconstant limit (+ *glob* 1)。

如果想知道某个符号是否是全局变量或常数的名字,请使用boundp。

> (boundp '*glob*)

T

赋值

CL中最普通的赋值操作符是setf。我们可以用它对全局或局部变量进行赋值:

> (setf *glob* 98)

98

> (let ((n 10))

(setf n 2)

n)

2

需要注意的是,如果要对一个变量赋值,必须先用let或者defparameter声明变量,否则会报warning。

函数式编程法

编写通过返回值来工作的程序,而不是它们的副作用。你使用副作用越少,你就越进步。

迭代

do宏是CL中最基本的迭代操作符。

(defun show-squares (start end)

(do ((i start (+ i 1)))

((> i end) 'done)

(format t "~A ~A ~%" i (* i i))))

上述代码中do宏只创建了一个变量i。第一次迭代时,i被赋予start的值,以后的迭代里,i的值每次增加1。

函数作为对象(Function as Objects)

LISP里函数和符号、字符串或列表一样,是稀松平常的对象。如果我们把函数名字传给function,它会返回相关联的对象。和quote类似,function是一个特殊操作符。

> (function +)

#

可以使用#'作为function的缩写,这个缩写称为升引号(sharp-quote)。

lambda

lambda表达式不是一个操作符,而只是一个符号。早期用于辨别列表与函数。Common Lisp里,你可以直接用列表来表达函数,函数在内部会被表示成独特的函数对象,因此不再需要lambda了。

((x) (+ x 100))

但Lisp程序员习惯用符号lambda来撰写函数,因此为了传统而保留了lambda。

defun

defun宏,创建一个函数并给函数命名。但函数不需要有名字,而且我们不需要defun来定义它们。我们可以直接引用函数,要直接饮用一个函数,我们使用所谓的lambda表达式。

(lambda (x y)

(+ x y))

lambda表达式可以是函数调用的第一个元素,lambda表达式还允许我们使用匿名函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值