[阅读笔记]读《计算机程序的构造和解释》之序言
3到4月份,用了五周时间修改了一个字典信息提取软件,在阅读那份软件的源代码的时候,我常常在想,我们目前所做的工作就是用程序表达,表达一系列由人脑构建的规则,表达人脑的思维的过程。那么,怎么更好的用程序表达,这需要知道计算机程序的表达规则和极限情况,《计算机程序的构造和解释》就是这样一本书,它从理论上讲述了程序的创建、执行和研究。这本书是MIT计算机科学的入门教材,作者基于以下两个原因写
3到4月份,用了五周时间修改了一个字典信息提取软件,在阅读那份软件的源代码的时候,我常常在想,我们目前所做的工作就是用程序表达,表达一系列由人脑构建的规则,表达人脑的思维的过程。那么,怎么更好的用程序表达,这需要知道计算机程序的表达规则和极限情况,《计算机程序的构造和解释》就是这样一本书,它从理论上讲述了程序的创建、执行和研究。这本书是MIT计算机科学的入门教材,作者基于以下两个原因写作了本书:
1. 一个计算机语言并不仅仅是让计算机去执行操作的一种方式,更重要的,它是一种表述有关方法学的思想的新颖的形式化媒介 。因此,程序必须写得能够供人们阅读,偶尔去供计算机执行。[怎样用程序表达 thinkhy 09/05/29]
2.在这一层次的课程里,最基本的材料并不是特定程序设计语言的语法,不是有效计算某种功能的巧妙算法,也不是算法的数学分析或者计算机的本质基础,而是一些能够用于控制大型软件系统的智力复杂性的技术 。[怎样控制程序表达的复杂性 thinkhy 09/05/29]
这是一本经典的计算机教科书,其中Alan J.Perils为本书作的序经常被人引用。序之前一页有这样一段引言:
带着崇敬和赞美,将本书献给活在计算机里的神灵。
"我认为,在计算机科学中保持计算中的趣味性是特别重要的事情。这一学科在起步时饱含着趣味性。当然,那些付钱的客户们时常觉得受了骗。一段时间之后,我们开始严肃地看待他们的抱怨。我们开始感觉到,自己真的像是负起成功地、无差错地,完美地使用这些机器的责任。我不认为我们可以做到这些。我认为我们的责任是去拓展这一领域,将其发展到新的方向,并在自己的家里保持趣味性。我希望计算机科学的领域绝不要丧失其趣味意识,最重要的是,我希望我们不要变成传道士,不要认为你是兜售圣经的人,世界上这种人已经足够多了。你所知道有关计算的东西,其他人也都能学到。绝不要以为似乎成功计算的钥匙就掌握在你的手里。你所掌握的,也是我认为并希望的,也就是智慧:那种看到这一机器比你第一次站在它面前时能做得更多的能力,这样你才能将它向前推进。" [我们需要掌握的是一种让自己不断学习、持续进步的能力 thinkhy 09/05/29]
下文转自:http://www.golden-book.com/product/MoreInfo.asp?id=26891&tid=5&sid2=fd6156f3217b
序
教育者、将军、减肥专家、心理学家和父母做规划(program),而军人、学生和另一些社会阶层则被人规划(are progfammed)。解决大规模问题需要经过一系列规划,其中的大部分东西只有在工作进程中才能做出来,这些规划中充满着与手头问题的特殊性相关的情况。如果想要把做规划这件事情本身作为一种智力活动来欣赏,你就必须转到计算机的程序设计(programming),你需要读或者写计算机程序——而且要大量地做。有关这些程序具体是关于什么的、服务于哪类应用等等的情况常常并不重要,重要的是它们的性能如何,在用于构造更大的程序时能否与其他程序平滑衔接。程序员们必须同时追求具体部分的完美和汇合的适宜性。在这部书里使用“程序设计”一词时,所关注的是程序的创建、执行和研究,这些程序是用一种Lisp方言书写的,为了在数字计算机上执行。采用Lisp并没有对我们可以编程的范围施以任何约束或者限制,而只不过确定了程序描述的记法形式。
本书中要讨论的各种问题都牵涉到三类需要关注的对象:人的大脑、计算机程序的集合以及计算机本身。每一个计算机程序都是现实中的或者精神中的某个过程的一个模型,通过人的头脑孵化出来。这些过程出现在人们的经验或者思维之中,数量上数不胜数,详情琐碎繁杂,任何时候人们都只能部分地理解它们。我们很少能通过自己的程序将这种过程模拟到永远令人满意的程度。正因为如此,即使我们写出的程序是一集经过仔细雕琢的离散符号,是交织在一起的一组函数,它们也需要不断地演化:当我们对于模型的认识更深入、更扩大、更广泛时,就需要去修改程序,直至这一模型最终到达了一种亚稳定状态。而在这时,程序中就又会出现另一个需要我们去为之奋斗的模型。计算机程序设计领域之令人兴奋的源泉,就在于它所引起连绵不绝的发现,在我们的头脑之中,在由程序所表达的计算机制之中,以及在由此所导致的认识爆炸之中。如果说艺术解释了我们的梦想,那么计算机就是以程序的名义执行着它们。 [这一点perils和knuth的所见略同,knuth曾经说过:为计算机准备程序 的过程非常吸引人,因为它不仅能带来经济和科学技术方面的回报,而且能给人以美的享受,就像写 诗 或 作曲一样。艺术本来就是能给人以美感的。 thinkhy 09/05/29]
就其本身的所有能力而言,计算机是一位一丝不苟的工匠:它的程序必须正确,我们希望说的所有东西,都必须表述得准确到每一点细节。就像在其他所有使用符号的活动中一样,我们需要通过论证使自己相信程序的真。可以为Lisp本身赋予一个语义(可以说是另一个模型),假如说,一个程序的功能可以在(例如)谓词演算里描述,那么就可以用逻辑方法做出一个可接受的正确性论证。不幸的是,随着程序变得更大更复杂(实际上它们几乎总是如此),这种描述本身的适宜性、一致性和正确性也都变得非常值得怀疑了。因此,很少能够看到有
关大程序正确性的完全形式化的论证。因为大的程序是从小东西成长起来的,开发出一个标准化的程序结构的武器库,并保证其中每种结构的正确性一—我们称它们为惯用法,再学会如何利用一些已经证明很有价值的组织技术,将这些结构组合成更大的结构,这些都是至关重要的。本书中将详尽地讨论这些技术。理解这些技术,对于参与这种被称为程序设计的具有创造性的事业是最最本质的。特别值得提出的是,发现并掌握强有力的组织技术,将提升我们构造大型的重要程序的能力。 [OO也可以说是一种组织技术 thinkhy 09/05/29] 反过来说,因为写大程序非常耗时费力,这也推动着我们去发明新方法,减轻由于大程序的功能和细节而引起的沉重负担。
与程序不同,计算机必须遵守物理定律。如果它们要快速执行——几个纳秒做一次状态转换——那么就必须在很短的距离内传导电子(至多1.5英尺)。必须消除由于大量元件而产生的热量集中。人们已经开发出了一些巧妙的工程艺术,用于在功能多样性与元件密度之间求得一种平衡。在任何情况下,硬件都是在比我们编程时所需要关心的层次更低的层次上操作的。将我们的Lisp程序变换到“机器”程序的过程本身也是抽象模型,是通过程序设计做出来的。研究和构造它们,能使人更加深刻地理解与任何模型的程序设计有关的程序组织问题。当然,计算机本身也可以这样模拟。请想一想:最小的物理开关元件在量子力学里建模,而量子力学又由一组微分方程描述,微分方程的细节行为可以由数值去近似,这种数值又由计算机程序所描述,计算机程序的组成…… [说到底计算机学科还是一种表达方法学 thinkhy 09/05/29]
区分出上述三类需要关注的对象,并不仅仅是为了策略上的便利。即使有人说它不过是人头脑里的东西,这种逻辑区分也引起了这些关注焦点之间符号流动的加速,它们在人们经验中的丰富性、活力和潜力,只能由现实生活中的不断演化去超越。我们至多只能说,这些关注焦点之间的关系是基本稳定的。计算机永远都不够大也不够快。硬件技术的每一次突破都带来了更大规模的程序设计事业,新的组织原理,以及更加丰富的抽象模型。[并行、分布式、云计算 ... ... thinkhy 09/05/29]每个读者都应该反复地问自己“到哪里才是头儿,到哪里才是头儿?”——但是不要问得过于频繁,以免忽略了程序设计的乐趣,使自己陷入一种喜忧参半的呆滞状态中。[基本的东西还是几十年未变,例如基本数据结构、经典算法、Unix API、Shell、C、OS体系 thinkhy 09/05/29 ]
在我们写出的程序里,有些程序执行了某个精确的数学函数(但是绝不够精确),例如排序,或者找出一系列数中的最大元,确定素数性,或者找出平方根。我们将这种程序称为算法,关于它们的最佳行为已经有了许多认识,特别是关于两个重要的参数:执行的时间和对数据存储的需求。程序员应该追求好的算法和惯用法。即使某些程序难以精确地描述,程序员也有责任去估计它们的性能,并要继续设法去改进之。
[下文开始讲Lisp thinkhy 09/05/29]
Lisp是——个幸存者,已经使用了四分之一个世纪。在现存的活语言里,只有Fortran比它的寿命更长些。这两种语言都支持着一些重要领域中的程序设计需要,Fortran用于科学与工程计算,Lisp用于人工智能。这两个领域现在仍然很重要,它们的程序员都如此倾心于这两种语言,因此,Lisp和 Fortran都还可能继续生存至少四分之一个世纪。[为什么是四分之一个世纪? thinkhy 09/05/29]
Lisp一直在改变着。这本教科书中所用的Scheme方言就是从原来的Lisp里演化出来的,并在若干重要方面与之相异,包括变量约束的静态作用域,以及允许函数产生出函数作为值。在语义结构上,Scheme更接近于Algol 60而不是早期的Lisp。Algol 60已经不可能再变为活的语言了,但它还活在Scheme和Pascal的基因里。很难找到这样的两种语言,它们能如此清晰地代表着围绕这两种语言而聚集起来的两种差异巨大的文化。Pascal是为了建造金字塔——壮丽辉煌、令人震憾,是由各就其位的沉重巨石筑起的静态结构。而Lisp则是为了构造有机体 ——同样的壮丽辉煌并令人震憾,由各就其位但却永不静止的无数简单的有机体片段构成的动态结构。 在两种语言里都采用了同样的组织原则,除了其中特别重要的一点不同之外:托付给Lisp程序员个人可用的自由支配权,要远远超过在Pascal社团里可找到的东西。Lisp程序大大抬高了函数库的地位,使其可用性超越了催生它们的那些具体应用。作为Lisp的内在数据结构,表对于这种可用性的提升起着最重要的作用。表的简单结构和自然可用性反应到函数里,就使它们具有了一种奇异的普适性。而在Pascal里,数据结构的过度声明导致函数的专用性,阻碍并惩罚临时性的合作。采用100个函数在一种数据结构上操作,远远优于用10个函数在10个数据结构上操作。作为这些情况的必然后果,金字塔矗立在那里千年不变,而有机体则必须演化,否则就会死亡。
为了看清楚这种差异,请将本书中给出的材料和练习与任何第一门Pascal课程的教科书中的材料做一个比较。请不要费力地去想象,说这不过是一本在MIT 采用的教科书,其特异性仅仅是因为它出自那个地方。准确地说,任何一本严肃的关于Lisp程序设计的书都应该如此,无论其学生是谁,在什么地方使用。
请注意,这是一本有关程序设计的教科书,它不像大部分关于Lisp的书,因为那些书多半是为人们在人工智能领域工作做准备。当然,无论如何,在研究工作规模不断增长的过程中,软件工程和人工智能所关心的重要程序设计工作正趋于相互结合。这也解释了为什么在人工智能领域之外的人们对Lisp的兴趣在不断增加。
正如由其目标可以预见到的,人工智能的研究产生出许多重要的程序设计问题。在其他程序设计文化中,问题的洪水孵化出一种又一种新的语言。确实,在任何非常大的程序设计工作中,一条有用的组织原则就是通过发明新语言,去控制和隔离作业模块之间的信息流动。这些语言趋向于变得越来越不基本,逐渐逼近系统的边界,逼近我们作为人最经常与之交互的地方。作为这一情况的结果,在这种系统里包含着大量重复的复杂的语言处理功能。Lisp有着如此简单的语法和语义,程序的语法分析可以看作一种很简单的工作。这样,语法分析技术对于Lisp程序几乎就没有价值,语言处理器的构造对于大型Lisp系统的成长和变化不会成为阻碍。最后,正是这种语法和语义的极端简单性,产生出了所有Lisp程序员的负担和自由。任何规模的Lisp程序,除了那种寥寥几行的程序外,都饱含着考虑周到的各种功能。发明并调整,调整恰当后再去发明!让我们举起杯,祝福那些将他们的思想镶嵌在重重括号之间的Lisp程序员。
Alan J.Perlis
纽黑文,康涅狄格
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)