一、LISP列表
'(rose violet daisy buttercup) '(this list has (a list inside of it))
LISP中的列表可以有三种可能的组成方式:括号和括号中由空格分隔的原子;括号和括号中的其他列表;括号和括号中的其他列表及原子。一个列表可以仅有一个原子或者完全没有原子。一个没有任何原子的列表,如(),被称作空列表。与所有列表都不同的是,可以把一个空列表同时看作既是一个原子又是一个列表。
二、LISP原子
数字、单个字符(如+)等都是lisp中的原子。在列表中,原子是由空格一一分隔的。原子可以紧接着括号。
LISP中的原子只有数字和符号两种。
原子和列表都被称作符号表达式(symbolic expression)或者更简洁的“s-expression”
三、LISP解释器的工作方式
a. '(this is a quoted list) b. (* 4 (+ 2 3))
将鼠标光标放在表达式的末尾,C-x C-e,分别得到解释结果为 (this is a quoted list)、20;上面命令的名称就是eval-last-sexp。其中“sexp”就是“symbol expression”(符号表达式)的缩写,“eval”就是“evaluation”(求值)的缩写。这个命令就是对最近一个符号表达式求值。
1.LISP解释器在对列表求值时:首先,查看一下列表前面是否存在一个单引号。如果有,那么,解释器定义为一个列表。如果没有单引号,那么查看列表中的第一个元素,并判断此元素是否为一个函数的定义。如果是一个函数定义,那么,解释器执行此函数定义的指令。否则,打印出错误信息。
2.LISP解释器对一个符号求值时,只要这个符号前面没有引号和括号包围它。LISP解释器会像变量一样来确定符号的值。出现这种情况是因为,一些函数异常并且以异常的方式运行。那些异常的函数被称为特殊表(special form)。他们用于特殊的工作,例如定义一个函数。
3.LISP解释器对于一个包含内部列表的列表进行求值时,首先找到最内层的内部列表,得到结果之后,依次向外解释。
LISP解释器能够解释的输入数据有源代码和字节编译代码两种,前者就是我们人能够看懂的最初的代码,后者则是通过特殊处理之后的代码,相应文件后缀分别是*.el\*.elc。
解释器处理一个表达式时,这个动作称为“求值”;也就是解释器计算表达式的值。完成表达式的求值之后,LISP解释器几乎总要返回一个值,这个值是计算机执行它在函数定义中找到的指令的结果,或者它放弃那个函数并产生一个错误消息。
解释器返回一个值的同时,也可以做些其他事情,例如移动光标或者拷贝一个文件,这种动作称为“附带效果”(side effect)。例如,打印一个文件,对LISP解释器而言常常是一个附带效果。
也就是,对于一个符号表达式求值几乎总是使LISP解释器返回一个值,同时可能产生一个附带效果,否则,产生一个错误消息。
四、LISP变量
在LISP中,可以将一个值赋给一个符号,也可以将一个函数定义赋给一个符号。这两者的含义是不同的。函数定义一组指令,并且由计算机执行。另一方面,一个值,比如一个数字或者一个名字,它的值是可以变化的。一个符号的值可以是LISP中的任意表达式(符号、数字、列表或者字符串)。有值的符号通常称为变量。
五、LISP参量
1. 参数的数据类型
2. 作为变量和列表的值的类型
(+ 2 fill-column)
(concat "The " (message "%d" (+ 2 fill-column)) " red foxes")
3. 数目可变的参量
( + )
( + 2 3)
(*)
(* 1 2 )
4. 用一个错误类型的数据对象作为参量
(+ 2 "hello")
5. message函数
(message "Hello,lisp world")
(message "The value of fill-column is %d" fill-column)
6. 给一个变量赋值
使用set函数
(set 'flowers '(rose violet daisy buttercup))
flowers
'flowers
使用setq函数
(setq carnivorse '(lion tiger leopard))
carnivorse
'carnivorse
setq中的q指的是quote,也就是说setq定义变量的效果通set函数定义的唯一区别就是变量前面是否需要加单引号
当然,除了set和setq赋值,还有另一种对这两个函数的理解,就是set和setq函数将符号指向列表。
计数
(setq counter 0)
(setq counter (+ counter 1))
counter