在任何的高级语言里面都需要标识符这么一个东西,从本质上来讲,标识符体现了数学中的方程的思想——对于计算机来说,标识符中所包含的数据是未知的,需要
从终端输入
的。因此他是个并不新鲜的东西,你只要编程就会天天见到:变量、常量还有函数名,都算是标识符。下面就我们最常用的标识符——变量开始。
还是要绕弯,在
c
语言里面我们如何使用一个变量呢?如下:
int a;
a=10;
虽然我们的步伐已经是第三章了,但是我们仍然要请出“裤衩原理”:在这里稍微说明下,因为
lisp
中完全没有必要声明一个变量是什么数据类型,所以
c
语言当中那个
int
a;
在
lisp
中完全没有必要出现——脱了裤衩
~
:
(a=10)
从我们已经学习的
lisp
的角度来看,这个表达式无疑相当奇怪,他的函数名在哪里?他的参数表在哪里
?
反正,不符合我们上一个章节给出的任何公式。所以我们来对比下
lisp
中赋值语句的正确形式:
(setq a 10)
正常情况下„„你肯定觉得不太对,貌似应该
(= a 10)
啊„„怎么出来个
setq
这么个东西?这真的没法解释,但是
lisp
里面就是这样定义的。现在我们来看看这个
s
表达式里
面有哪几个标识符。首先,
a
作为一个变量,那必须是标识符,然后,
setq
作为一个函数名,标识符的身份他是跑不了的了。等等,函数名也是标识符?!那么“+”呢„„同样
的,标识
符!
如果我写到这里就结束这一章的话,我一定是偷懒会周公或者去和女朋友约会了(后者可能性太小了„„),所以这里必须继续写:提出一个新的概念——原子(
atom
)。
什么是原子,我可以肯定的是原子肯定是标识符(标识符的概念实在太大了),但是,对于一个标识符,我们在没有明白(注意是“明白”,我不认为这个东西大部分人可以通
过维基百科搞清楚“原子”这个东西)原子的定义的时候,只好通过一个函数来进行验证:
(atom
要验证的标识符
)
举例来说:
(atom 9)
输入到你的
lisp
环境里面,答案是“T”。你现在已经看到两个原子了,一个是
9
,一个是“T”。要搞明白
9
是不是原子,看样子我们这里必须明白“T”是
什么——我们这次
又是换个“裤衩”——“T”就是
lisp
里面的
true
,当然他的小写形式“t”也是
true
的意思,两者没有区别。那么对应
的,
false
的对应
lisp
形式是什么呢?是“NIL”,你
小写的话,“nil”也没有问题。
现在我们可以确定,
9
是一个标识符,于是,所有的数,只要是实数范围内的数都是原子。
现在继续尝试
,
还记得我们的
"hello world"
不?
(atom "hello world")
答案是显然的,字符串也是个原子。应用同样的方式,你可以确定“T”也是个原子,但是“NIL”不知。
我们现在找一个没有声明过的变量来实验下吧
~
(atom a)
额,你现在可以看到,貌似有点问题,出来一大堆错误信息,但是就是不给你结果,苍天,哪怕给我个“NIL”也可以啊„„因为这个变量没有声明过,系统不知道他是个函数名
还是个普通的变量„„而这不确定足以导致错误,足以让我们看着那堆洋码子发狂。
我们现在想办法声明下
a
,有两个途径:给
a
赋值,定义
a
是一个函数。
先是给
a
赋值吧:
(setq a "hello world")
(atom a)
答案显示“T”。这个时候系统不把
a
看作是函数名,而是一个存储着数据的变量(你要是想要让
a
存储个数字,比如
10
,也是一样的),当然这就没有问题。然后再来个函数?
就用我们前面写的那个很累赘的
add
函数吧:
(atom add)
可能到这里有点同学就有感觉了,应该也会弹出一大堆错误信息,而事实也确实如此。
我们来验证一下这些已经验证过的原子和那些报错的标识符相比有什么特点:这些原子都是已经声明过的,存贮者明确的数据的标识符——没有声明过的
a
因为没有存储明确的
数据所以报错,而
add
虽然声明过,但是他的两个参数显然没有赋予数据,所以他也会报错。
很多同学到这里已经晕掉了:这都是什么啊?!