7 O9 F9 [6 h% zlisp的优势是它是基于数学的,所以核心部分非常小,1k内存就能完成全部解释器,剩下的功能都可以用lisp本身代码来实现,所以也是那个时候高级语言唯一的选择。lisp里面大量用到表,而这个表是用链表实现的,这也是节省内存的一个巧妙设计。因为链表在取它的后半部分,或者在头部添加内容的时候(在尾部进行改变则不行),可以共享后部的相同部分,这样就可以在进行数据操作的时候节省大量拷贝内存、分配新内存的工作。这也是lisp最早发明内存垃圾收集器的原因。 ) S) Z2 w$ w2 v2 x- |8 _ Y8 |) Z5 b3 U; j( W# F
c语言发明的时候,节省内存用的办法就是把编译任务尽可能拆开,中间结果用文件缓存,进行下一步的时候就把上一部处理的程序丢出内存。' m+ R" y, M f
具体说,你要统计一个1M的文本里面出现了多少个the,需要多少内存?只要几十个字节。因为你扫描文件的过程当中无需保存中间结果,只有在扫描到了符合一半的时候需要保存一下中间结果,然后是一个变量。同样,你编译的时候,只需要一个符号表(保留字,常量变量,宏,函数定义)和一个临时符号表(函数内部变量),然后一个函数相关的跳转表(每个函数内部的for循环,if语句和goto语句要跳到的地址),一个数学表达式解析表,剩下的因为都是上下文无关,所以一边读,在缓冲区转换,存到目标文件,不用放到内存。通共只要几k就行了。如果符号表太大,甚至符号表也可以放到临时文件里面。真正占内存的都是上下文相关的数据。 ( M3 i# ?1 ^0 {. P所以大家会看到头文件这种设计,因为这样就可以不用把其他文件的编译信息都读进来。函数要定义才能使用也是一样。花括号和+=等操作也是为了减少程序空间大小。因为当时内存实在太宝贵了。著名的switch语句的缺省没有break也是一样的。4 m9 U6 F4 i6 m* p
1 Y3 n" e L' x0 a) o$ V从这一点看,和c同时发明的pascal,都是algol语言的继承者,在这一点上就设计的更好一些,抛弃了很多工程上的小聪明。如果不涉及系统编程,比如大量频繁的内存分配,两者的语法几乎是等价的,而pascal语言的程序相对而言清晰得多,更不容易产生错误。库的处理,中间代码P code的处理,都非常巧妙。如果不是c那样的超级通用语言(可以进行系统编程)的话,pascal本来可以成为一种更流行的语言,从而让现在的软件工程更正规一点。毕竟,个人电脑发明后,由于摩尔定律,内存的增加让c为节省的那点内存进行的操作完全成了多余而添麻烦的行为了。7 c0 u* Z/ }- E* f' H