转自渔阳(乱世华尔街作者)的博客: http://blog.sina.com.cn/s/blog_72b0a6e10100sdqf.html
最近新浪博客和天涯讨论贴中总有网友让我推荐金融类的好书。我整理了一个单子,都是我读过的,欢迎补充。先说明一点:格雷厄姆和巴菲特那一派的书我读的少,主要因为他们是“气宗”(Real Money),投行是“剑宗”(Fast Money),路数不太一样。那一派的经典书也是应该读的。实际上商学院和CFA等“正统科班”教的估价理论都源自格雷厄姆,所以我也算间接读过《证券分析》等基本分析派的名著。
书单如下,中文译名在括号内:
第一类书是关于交易手法、风险控制、心理建设、名家思维的,投资者/投机者必读,尤其对股票、期货、外汇交易很有帮助。
Reminiscences of a Stock Operator(股票作手回忆录):投机性交易的超级经典,虽然讲的是100多年前的事,但许多现代高手均对其极为推崇。 书中以主角利弗莫尔的交易生涯为线索,讲述了很多交易心理、技巧、常见错误、注意事项等。 书中还有做庄方法的讲解。 这本应是股票投资者的必读书。
Market Wizard(市场奇才):多位成功投资者/投机者的采访录,从受访者的言谈中可以领略许多精彩的投资理念和“小窍门”,比如输钱时应逐步减仓,市场“无理由”突然运动应立即跟进等。 此书写于1980年代末,书中的几位受访者,如Bruce Kovner, Paul Tudor Jones等人在此书出版之后的20年间跻身世界上最成功的对冲基金经理行列,对他们的采访应重点阅读。 另外,William O’Neil选股票的CANSLIM法则很值得借鉴。
New Market Wizard(新市场奇才):与上一本类似。
Inside the House of Money(黄金屋):讲述对冲基金行业的好书,以对基金经理的访谈为主,类似《市场奇才》。
The Great Game(伟大的博弈):这本书的英文原版并不太有名,但中文译本却很有名。此书记述了华尔街几百年来的发展史,像一部华丽的纪录片,故事性强,帮助读者“温故知新”。
《十年一梦》:国内实战派写手的好书,讲了不少国内市场发展的掌故。作者的心路历程颇能引起共鸣,也再次告诉我们风险控制的重要性,投资者最好不要经历作者经历的那种大起大落。
《投机者的扑克》:与上一本类似。
《炒股的智慧》:一本很薄、很朴实、很实用的书。作者是拥有丰富美股交易经验的个人投资者。此书讲的都是大道至简的道理,但每隔几年拿出来翻翻,都能有新的体会。(感谢网友“东方甲子木”提醒,增加此书。)
A Random Walk Down Wall Street(漫步华尔街):学院派的超级经典。基本的意思就是:上面那些书都甭看了,市场是不可战胜的,股票走势完全随机,作为普通投资者,买指数基金就好了,图个省钱(管理费低)、省心。 这本书我没看过,但对其讲述的学院派“有效市场理论”很熟悉。 简而言之,就是市场价格已经包含了一切已知信息,所以基本分析和技术分析都没用。 我认为此理论过于极端,索罗斯等大牛的业绩就是反证。 然而,有效市场理论是非常好的出发点,我对它的辩证理解是:想战胜市场,不潜心修炼、不下苦功不行。而且,多数时候市场对我都是“有效”的(我没仔细研究过,无法下结论)。所以网友的投资问题我一般都说不知道(谨记“有效市场”,不可妄下结论)。 我认为,那些随便看看图线就能告诉你走势的“砖家”言论都不必认真。对普通投资者而言,买指数基金,图个省钱、省心,多点时间享受生活不失为好建议。 (感谢网友天涯大牛“海宁”提醒,增加此书。)
第二类书是关于金融市场、投资银行、对冲基金的,想入行者必读。一般投资者可以当故事看看,增加背景知识。
Liar’s Poker (说谎者的扑克牌):Michael Lewis的成名作,以风趣幽默的语言描绘了1980年代美国投资银行生态以及债券市场的发展过程,其间穿插路易斯本人在所罗门兄弟公司经历的种种小故事。 这本书被认为是投行“新鲜人”的必读书籍。 我就是看了这本书后,才对债券交易产生了浓厚兴趣。
When Genius Failed (赌金者,营救华尔街):完整记述长期资本管理公司兴衰史的金融纪实经典之作。书中记述的历史仿佛是2008年金融危机的“彩排”。
Barbarian at the Gates(门口的野蛮人): 另一部金融新闻纪实的经典之作,记述了1980年代末的一桩史上最大的杠杆收购案例,是了解投资银行(Investment Banking)业务的必读书。
FIASCO(泥鸽靶,诚信的背后):了解衍生产品的好书。记述了1990年代摩根斯坦利使用各种“创新”衍生产品牟利的故事。 从中可以学习复杂衍生产品存在的“逻辑”:帮助客户解决某些问题。
The Big Short(大空头):记叙一些精明的投资者如何在次贷危机中大获其利的书。作者是写《说谎者的扑克牌》的路易斯。
什么,您的时间有限,这些书读不过来? 希望看一本有点搞笑、有点故事、有点历史、有点心得的“什锦大杂烩”?那我只能“内举不避亲”了,看看《乱世华尔街》吧。:)))))
Friday, June 3, 2011
Sunday, November 7, 2010
介绍一下维特根斯坦
作者: feifei 转自: http://book.douban.com/review/1629135/
维特根斯坦在当代可算是最重要的哲学家(可能没有之一),他的《哲学研究》也被评为近五十年来最重要的哲学著作(参见豆列 www.douban.com/doulist/165269),可见他在西方的地位。然而他在中国却未能获得应有的关注度,特别是在大众中。在哲学的热度达到顶峰的八十年代,他却在中国的哲学界销声匿迹,其实他在四十年代便被带到中国。总而言之,他不是受大众欢迎的哲学家,他讨论的问题大众也不感兴趣。因此有人说,维特根斯坦是面向哲学家的哲学家。
一切从语言说起
维特根斯坦的哲学可以分成前后两个截然不同的阶段,两者的差别甚至使他的著作好像出自两个人之手。然而其中有一条线索贯穿这两个阶段,那就是语言问题,准确的来讲,是语言与哲学的关系,这种哲学主要是指形而上学。前期注重的是语言的局限性,认为语言所表达的东西是有限的,而哲学问题恰恰就在语言世界之外。因此,哲学问题就属于不可言说的范围,哲学问题应该在我们的语言中消失。后期的维特根斯坦强调的是语言的多样性,认为哲学问题源于哲学家未能理解日常语言的多样性而产生了对语言的误用,并在运用语言的时候背离了它的日常用法。这个观点下面会仔细的说,总而言之,当我们了解了语言的特性,哲学问题就会随之消失。用两句话总结维特根斯坦前后期的语言观,那就是有些事我们不能说,而有些事我们不能说清楚。
他的书适合一些话多或者爱较真的人来读。读了他的书,我发现我的话少了,不知是不是好事,不过同时废话也少了,而且发现别人的废话也不少。
要了解维特根斯坦的语言观所针对的标靶,只需看一下高中的政治课本就可以了。例如马克思建立的那种用一个理论就可以把天下所有事情都解释一通的体系,显然就是维特根斯坦一直反对的哲学企图,而教科书上例如“矛盾”、“物质”之类的说法则显然违背了这些词的日常用法。我曾在教科书上看见过一个论证:3-2=1,式子中3和-2一正一负,构成矛盾,最后得出结果1,这证明了数学在矛盾中辩证地运动。事实上,在我们对矛盾的日常用法中,我们会说如果得出3-2既等于1又等于3,那就是矛盾,我们却从不会说3-2=1里面有“矛盾”。
当然,他针对的并不仅仅是马克思,而是一种唯理主义传统,它认为世界上所有事物都可通过理性弄清,我们也可以通过语言精确的阐释一切事物。
介绍几本书
1、哲学研究 http://www.douban.com/subject/1315184/?i=0
如果你没时间只能看他的一本书,那我建议你看这本。实在太忙的话,那看前面几十页就可以使你获益良多了。阅读这本书的过程就是一个纠正我们使用语言的错误的过程。
我们经常都会提出像“xx是什么?”这种形式的问题,例如生命是什么。维特根斯坦认为这个问题的关键并不是要理解生命的“本质”,而是要理解 “生命”这个词的用法。两个优秀的生物学家也会为病毒是不是生命而争吵,其实他们都很了解病毒,只是他们对生命这个词的用法有分歧罢了。这不是生物问题,而是语言问题。很多哲学问题其实也是一种语言问题。
在生活中我们也遇到这种情况,A和B在争论C是不是好人,他们对C做过什么事都很清楚,没有分歧,然而他们还是会争吵,其实也只是因为他们对好人的定义有不同而已。知道这一点,我们就会明白很多争论都没有进入问题的实质。
语言的意义在于它的用法,他得出了这个结论,这只是他整本书的一个起点而已,后面还有很多重要的观点,碍于能力所限就不说了。提一下对我启发最大的“家族相似”论点。我们经常用一个词指代一类事物,如用金属来指金、银、铜等物质,马来指白马黑马等多种马,似乎各个事物因为有一种本质的相似,所以我们要用一个词称呼他们。维特根斯坦认为这只是一种“家族类似”,一类事物就象一个家族,他们的样子有些相似,然而他们的行为、思想却很可能有很大不同。例如,我们习惯把文化分成东方文化和西方文化两类,似乎两者之间有一道鸿沟。然而在东方文化内部果真有种本质上的共同点吗?老子与孔子的区别要比孔子与苏格拉底的区别要少吗?也许看了哲学研究,我们会对一切以集体名义作出的行为保持警惕。
2、论确实性http://www.douban.com/subject/1013410/?i=0
这本书是他的遗作,比哲学研究还要凌乱,然而如果你已经对它感兴趣,这本书还是值得一读。这本书围绕着一些我们称之为公理的东西而展开,例如物质在我看不到的时候依旧存在、每个人都有父母。维特根斯坦研究我们为什么会确信这些命题,他认为并不是这些命题无法怀疑,而是我们的生活决定了我们的怀疑没有意义,因为如果我们怀疑,我们就无法生活。例如我们原本可以怀疑自己其实身处黑客帝国,这理论上完全有可能,但你如果真的这么想,我们就会以为你是疯子,因为你的怀疑触及了生活的根本。相反,怀疑相对论却是可以接受的,因为相对论还离我们的日常生活很远,尽管你的怀疑已被很多实验否定。
3、逻辑哲学论http://www.douban.com/subject/1005354/
前期代表作。可以找到很多适合用作签名档的警句,可是不推荐阅读,在现在看来,这本书的现实意义不大。
终于写完了,算是对思想的一次整理吧,大脑的混沌状态终于要结束了...
维特根斯坦在当代可算是最重要的哲学家(可能没有之一),他的《哲学研究》也被评为近五十年来最重要的哲学著作(参见豆列 www.douban.com/doulist/165269),可见他在西方的地位。然而他在中国却未能获得应有的关注度,特别是在大众中。在哲学的热度达到顶峰的八十年代,他却在中国的哲学界销声匿迹,其实他在四十年代便被带到中国。总而言之,他不是受大众欢迎的哲学家,他讨论的问题大众也不感兴趣。因此有人说,维特根斯坦是面向哲学家的哲学家。
一切从语言说起
维特根斯坦的哲学可以分成前后两个截然不同的阶段,两者的差别甚至使他的著作好像出自两个人之手。然而其中有一条线索贯穿这两个阶段,那就是语言问题,准确的来讲,是语言与哲学的关系,这种哲学主要是指形而上学。前期注重的是语言的局限性,认为语言所表达的东西是有限的,而哲学问题恰恰就在语言世界之外。因此,哲学问题就属于不可言说的范围,哲学问题应该在我们的语言中消失。后期的维特根斯坦强调的是语言的多样性,认为哲学问题源于哲学家未能理解日常语言的多样性而产生了对语言的误用,并在运用语言的时候背离了它的日常用法。这个观点下面会仔细的说,总而言之,当我们了解了语言的特性,哲学问题就会随之消失。用两句话总结维特根斯坦前后期的语言观,那就是有些事我们不能说,而有些事我们不能说清楚。
他的书适合一些话多或者爱较真的人来读。读了他的书,我发现我的话少了,不知是不是好事,不过同时废话也少了,而且发现别人的废话也不少。
要了解维特根斯坦的语言观所针对的标靶,只需看一下高中的政治课本就可以了。例如马克思建立的那种用一个理论就可以把天下所有事情都解释一通的体系,显然就是维特根斯坦一直反对的哲学企图,而教科书上例如“矛盾”、“物质”之类的说法则显然违背了这些词的日常用法。我曾在教科书上看见过一个论证:3-2=1,式子中3和-2一正一负,构成矛盾,最后得出结果1,这证明了数学在矛盾中辩证地运动。事实上,在我们对矛盾的日常用法中,我们会说如果得出3-2既等于1又等于3,那就是矛盾,我们却从不会说3-2=1里面有“矛盾”。
当然,他针对的并不仅仅是马克思,而是一种唯理主义传统,它认为世界上所有事物都可通过理性弄清,我们也可以通过语言精确的阐释一切事物。
介绍几本书
1、哲学研究 http://www.douban.com/subject/1315184/?i=0
如果你没时间只能看他的一本书,那我建议你看这本。实在太忙的话,那看前面几十页就可以使你获益良多了。阅读这本书的过程就是一个纠正我们使用语言的错误的过程。
我们经常都会提出像“xx是什么?”这种形式的问题,例如生命是什么。维特根斯坦认为这个问题的关键并不是要理解生命的“本质”,而是要理解 “生命”这个词的用法。两个优秀的生物学家也会为病毒是不是生命而争吵,其实他们都很了解病毒,只是他们对生命这个词的用法有分歧罢了。这不是生物问题,而是语言问题。很多哲学问题其实也是一种语言问题。
在生活中我们也遇到这种情况,A和B在争论C是不是好人,他们对C做过什么事都很清楚,没有分歧,然而他们还是会争吵,其实也只是因为他们对好人的定义有不同而已。知道这一点,我们就会明白很多争论都没有进入问题的实质。
语言的意义在于它的用法,他得出了这个结论,这只是他整本书的一个起点而已,后面还有很多重要的观点,碍于能力所限就不说了。提一下对我启发最大的“家族相似”论点。我们经常用一个词指代一类事物,如用金属来指金、银、铜等物质,马来指白马黑马等多种马,似乎各个事物因为有一种本质的相似,所以我们要用一个词称呼他们。维特根斯坦认为这只是一种“家族类似”,一类事物就象一个家族,他们的样子有些相似,然而他们的行为、思想却很可能有很大不同。例如,我们习惯把文化分成东方文化和西方文化两类,似乎两者之间有一道鸿沟。然而在东方文化内部果真有种本质上的共同点吗?老子与孔子的区别要比孔子与苏格拉底的区别要少吗?也许看了哲学研究,我们会对一切以集体名义作出的行为保持警惕。
2、论确实性http://www.douban.com/subject/1013410/?i=0
这本书是他的遗作,比哲学研究还要凌乱,然而如果你已经对它感兴趣,这本书还是值得一读。这本书围绕着一些我们称之为公理的东西而展开,例如物质在我看不到的时候依旧存在、每个人都有父母。维特根斯坦研究我们为什么会确信这些命题,他认为并不是这些命题无法怀疑,而是我们的生活决定了我们的怀疑没有意义,因为如果我们怀疑,我们就无法生活。例如我们原本可以怀疑自己其实身处黑客帝国,这理论上完全有可能,但你如果真的这么想,我们就会以为你是疯子,因为你的怀疑触及了生活的根本。相反,怀疑相对论却是可以接受的,因为相对论还离我们的日常生活很远,尽管你的怀疑已被很多实验否定。
3、逻辑哲学论http://www.douban.com/subject/1005354/
前期代表作。可以找到很多适合用作签名档的警句,可是不推荐阅读,在现在看来,这本书的现实意义不大。
终于写完了,算是对思想的一次整理吧,大脑的混沌状态终于要结束了...
维特根斯坦论确实性——从摩尔对怀疑主义的反驳说起
作者: 西江月, 转自: http://book.douban.com/review/2073062/
康德曾在其《纯粹理性批判》第二版序言中提到哲学和普遍人类理性的丑闻,即理性之无法真正反驳怀疑主义:“唯心论尽可以就形而上学的根本目的而言仍然被看作是无辜的,然而哲学和普遍人类理性的丑闻仍然存在,即不得不仅仅在信仰上假定在我们之外的物的存有,并且,如果有人忽然想到要怀疑这种存有,我们没有任何足够的证据能够反驳他” 。
针对这一丑闻,摩尔(George Edward Moore)在《外在世界的证明》(1939年)一文中做出了他的回答。摩尔认为他可以给出数量庞大的不同证明来反驳怀疑论者。“比如,我现在就可以证明存在两只手。如何证明呢?通过举起我的两只手,并且在我用右手做出某个手势时说‘这里有一只手’,而在用左手做出某个手势的时候补充‘这里还有另一只手’。” 摩尔继续说,如果这个证明成立,那么显然他还能举出更多其它证明。
但摩尔的这种证明显然不能让许多哲学家感到满意,因为摩尔并不能对“这里有一只手”和“这里还有另一只手”这些前提给出证明。摩尔对此说道: “虽然我不能对一些事情给出证明,但我仍然能够知道它们。”关于这一点,摩尔也曾在《为常识辩护》(1925年)一文中提到,存在一系列命题,“对于其中任何一个,我都确信地知道为真。”这一系列命题包括:“我有身体,它在过去某时出生,并且从那以后一直停留在地球附近”,“在三维空间中存在许多其它有形状大小的东西”,“除了我自己以外还有别人”,“地球在我出生之前很久就已存在”等等。
摩尔究竟有没有对怀疑主义做出有效的反驳?其对外在世界的证明是否有效?对此,维特根斯坦在《论确实性》一书中指出,摩尔对怀疑主义的反驳根本不得要领。摩尔并不知道怀疑主义者的怀疑在何种意义上是非法的,因此并不能对其做出有效的反驳。在维特根斯坦看来,怀疑论者对外在世界之存在的怀疑之所以不合法,原因并非在于外在世界确实存在,而在于他们的怀疑本身是有问题的。在此意义上,摩尔对于怀疑论者看似有力的正面回击,即证明外在世界如何的确存在,就成为不得要领的了。此外,摩尔用“我知道……”来证明外在世界的存在,恰恰暴露出他根本不知道“知道”一词的正确用法,而错将“知道”等同于一种绝对的确实性。
在《论确实性》这本书里,维特根斯坦认为,反对怀疑主义并不意味着支持绝对的确实性。恰恰相反,确实性只相对一种体系、世界图景、语言游戏而言,即任何命题的确实性只是相对的。即便是摩尔所举出的貌似无可反驳的命题,也只具有相对的确实性。因为关于外在世界,我们所拥有的至多不过是一些不可穷究其根据的基本信念。不过,对于这些信念我们虽然无法拥有绝对的确信,但亦无法怀疑,因为我们向来就生活在这些基本信念之中。只是在此意义上,怀疑主义才是无效的。
一、 摩尔不知道“知道”的正当用法
维特根斯坦指出,摩尔错误地使用了“知道”这个概念。摩尔认为,“知道”这一陈述“不可能是一种错误”。维特根斯坦指出,摩尔在这里忽视了 “知道”背后隐藏的“我相信我知道”的公式。“因为‘我知道’似乎是描述一种事态,这种事态保证所知的东西是一种事实,人们总是忘记‘我认为我知道’这个表达。”
在维特根斯坦那里,“知道”的正当用法如下:“‘我知道’经常表示这样的意思:我有正当的理由支持我说的语句”。而能够为某事提供正当理由并不意味着某事是绝对正确的,或言具有一种绝对的确实性,恰恰相反,具有正当理由意味着不具有正当理由情形,即“错误”的可能性。知识和错误是一对相伴相生的概念。凡我们所知道的东西,都有犯错的可能性。因为“说出‘我知道’这种保证是不够的,因为我不可能弄错毕竟只是一种保证,而在那件事上我不可能弄错却需要在客观上加以证实”。
这也意味着,“知道”和“出错”的使用是有界限的。维特根斯坦认为,对于一些无法用真假对错去评判的、关涉生活世界基础的基本信念,我们无法说“我知道”或“出错了”。“知道”所处的是日常的体系内部的因果链条,它在体系内部中可以进行有效的运作;但是对于那些规定了体系本身、规定了世界和语言界限的基本命题,我们可做的只有相信。一个人可以有效地计算,但是却无法为计算的确实性找到绝对的证明,因为一切诸如“这是老师教我的”之类的解释最终会走到尽头:“如果有人教某个人学计算,那么是否也要教他:他能够依靠他老师的计算?但是这些说明到时候毕竟会走到尽头”,“难道验证不是终有个完结吗?”。在穷尽处,即基本信念领域,我们不可再问根据,而只需相信。
二、关于基本信念、确实性和世界图景
这些基本命题或基本信念首先包括,比如摩尔所说的“我有一只手”,或者“我是一个人”、“我有大脑”“地球在我出生之前很久就已存在”等等。对于这些命题,既无法说真,亦无法说假。而之所以如此,其中理由并不在于怀疑论者所提出的感觉经验的可骗性,或是摩尔提出的常识辩护,而仅仅在于,这些命题是我们生活中的基本信念,它们构成了其它信念之所以可能的基础。一般情况下,对于这些命题既无法谈“知道”,亦无法谈“出错”。在此意义上,这些命题是不可怀疑的。在这些基本信念上出问题,关涉的不是错误,而是精神问题。“如果我的朋友有一天想像他在某某地方已经住了很长一段时间,等等,等等,我不会把这件事叫做错误,而是叫做精神失常,也许是暂时性的精神失常。”以此类推,没有特殊理由的不知道他有一只手或他是一个人,也只能被归于精神失常。
这些基本信念来源于人们的生活共同体,来自人们习以为常、约定俗成的使用,来自“没有理由的行动方式”。由于这些信念规定了我们日常生活的基本框架,所以它们的反面在通常情况下是不可想象的。“表达摩尔所‘知道’的事物的命题都属于这样一类命题,即很难想像一个人为什么应当相信其反面。例如那个讲摩尔已经贴近地球生活了一辈子的命题。……我看到的和听到的所有事物都让我确信没有人曾远离地球。在我的世界图景中没有一件事物支持其反面的说法。” 这些命题是“一切思想(语言)运作的基础”,是“我们思想的框架”,是“我一切行动的基础”,以故,虽然维特根斯坦批评摩尔采取了错误的方式去维护常识,但摩尔的维护常识的态度的确为维特根斯坦所赞同。“维特根斯坦相信摩尔所列举的命题的程度绝不亚于摩尔本人。”
当然,这并不意味着这些命题具有自明的绝对的确实性,而只是因为既然我们处于共同体之中,我们便没有理由不相信,也不可能不相信。这些基本信念既然来自人类生活共同体,就必定是历史性的,有诞生有消灭。一些在这代人那里曾经是基本信念的,到了下代人就不一定还是基本信念。在此,维特根斯坦有一个极为生动的比喻,他将生活比作河流,而将基本信念比作通道或河床:“可以想像,一些经验命题得以凝结,对其后来凝结的,仍然是有流动性的命题起到作为通道的作用;也可以想像,随着时间的推移,上述关系将发生变化:曾经具有流动性的命题获知凝结,而曾经凝结了的命题,变得具有流动性”。“这种神话可能变为原来的流动状态,思想的河床可能移动。”
在维特根斯坦那里,并不存在绝对的确实性,确实性仅仅具有相对的含义,仅仅针对某一民族某一阶段的生活而言。在此意义上,确实性只是虚的东西:“确实性就像是一种语气,人们用这种语气肯定事态,但是人们并不是从语气中推导出这样说就有道理”。确信并不是推理的基础,而只是所有推理之可能进行的前提。依靠这种虚的确定性,人们才能建立起所有一般信念,并在其中做有效的推理。海德格尔也曾经向我们揭示出“虚”的重要性。他指出我们的文化往往并非关注实的东西,那些由实的东西承载的虚的东西才是关键。此在的意义在于虚的东西。种种虚的指引让人烦劳操心,虚的时间性结构是此在的本质结构。维特根斯坦和海德格尔在很多方面不一致,但却不约而同地指出了如下一点,即:人们往往刻意地努力去追求实在,却不知自己总已处身于虚之中。
而仅仅具有相对确实性的基本信念必定总已处于一个体系之中。在信念之流之中,河床的沉积或者被冲刷与流水相关。没有任何一个命题具有绝对的确定性,意味着没有任何一个命题能够被单独抽离来看——所有命题都属于一个相互依赖的体系。“某些经验命题的真实性(Wahrheit)属于我们的参照系(Bezugssystem)。”“使我认为明显无误的并不是一些单独的公理,而是一个前提与结论互相支持的体系。”“某个信念之所以占有稳固的地位,与其说是由于其本身显而易见或令人信服,倒不如说是靠其周围的信念才使它不可动摇。”“有关一种假设的一切检验、一切证实或否证都早已发生在一个体系之中。这个体系并不是我们进行一切论证时所采用的多少带有任意性或者不太可靠的出发点,而是属于我们称之为论证的本质。这个体系与其说是论证的出发点,不如说是赋予论证以生命的活力。”这个体系自身并不绝对确实,但是却构成相应人群生活的统一背景,是一切论证和检验可以生效的前提。换言之,这个体系是一个共同体的世界图景。对此维特根斯坦说道:“我有一个世界图景。这个世界图景是真还是假?最重要的在于它是我的一切探讨和断言的基础。那些描述它的命题并不是全都同样受到检验的制约。”
不同时代有着几乎完全不同的世界图景。在古希腊人那里,他们的祖先和奥林匹亚诸神以各种方式渗透了他们的生活;在中世纪的欧洲,上帝是最高的实在,存在地上之城和上帝之城两个世界;而在不信神的现代人眼前展现的,则是科学的客观的世界图景。即便是在同一时代,不同地域人们的世界图景亦有天差地别,比如当今美国人民与非洲某原始部落之世界图景的差别。甚至即便是在同一时代、同一地域的人们,也有可能拥有彼此相异的世界图景,比如基督徒与无神论者。在自然环境、社会、以及各种偶然因素的影响下,人们从各自的实践中沉淀出属于自己种群的独特的世界图景。而不同的世界图景意味着不同的基本信念体系,意味着不同的语法规则,并在此意义上无所谓优劣差等。身处某一世界图景之中的人们总是以自己的世界观为正确,并力图让处于其外的人们也接受它。维特根斯坦将这种世界图景等同于一种积极意义上的神话:“描述这幅世界图景的命题也许是一种神话的一部分,其功用类似于一种游戏的规则。这种游戏可从全靠实践而不是靠任何明确的规则学会。”
三、基本信念说意味着什么
1怀疑主义者的怀疑是非法的
维特根斯坦反对怀疑主义,但他的反对并非出于对绝对确实性的相信——像摩尔所以为的那样。维特根斯坦只承认一种相对的确定性,但相对的确定性将并不导致怀疑主义,而恰恰将揭示出,怀疑论者所说的怀疑是没有意义的。我们向来总已生活在一个统一背景之中,基本信念规定了我们思想和语言的框架,在此意义上,要想进行彻底怀疑是根本不可能的。“如果你想怀疑一切,你就什么也不能怀疑。怀疑这种游戏本身就预先假定了确实性。”“如果你什么事实也不确知,那么你也就不能确知你所用的词的意义。”“怀疑出现在信念之后。”“我知道”是怀疑之可能的基础。若不能说“我知道”,就不能说“我怀疑”。“对于一种存在的怀疑只能在一种语言游戏中进行。”“一种怀疑一切的怀疑就不成其为怀疑。”“这表明不容怀疑属于语言游戏的本质”,而语言游戏归根结底乃是一种生活形式,“因为行动才是语言游戏的根基”。“我们不怀疑所有这些事实只是我们的判断方式,因而也就是我们的行为方式。”
事实上,康德所说的“哲学和普遍人类理性的丑闻”直接来自休谟的怀疑论。而维特根斯坦之所以能够成功地抵制休谟的怀疑论,其原因恰恰在于维特根斯坦在一定程度上承认了休谟的前提,即因果关系本不是必然的,我们日常以为真的只是些暂时固定下来的信念,并不必然真。但是,正是在此意义上,跳出基本信念的圈子去绝对怀疑才是不可能的。人无法离开生活之流而在地面上进行观察,因为这样的地面根本就不存在。而摩尔对怀疑主义不恰当的反驳透露出,摩尔其实既不知道“知道”,也不知道“怀疑”。
2自笛卡儿以来的对知识确定性的追求被宣布为无效
在《第一哲学沉思集》中,笛卡儿致力于通过彻底怀疑找出人类知识的最后支点,即我们能够绝对确信的东西:“我思故我在”。笛卡儿相信由此他便可以重建人类知识大厦,并最终克服怀疑主义。而在维特根斯坦看来,根本上说,是因为笛卡儿非法地使用了怀疑概念,才构建出所谓绝对确信的东西。而事实是,我们始终在生活的河流之中,所能触及的只能是暂时或者相对持久地沉积下来的河床。我们无法怀疑这些沉淀下来的东西,因为它们是我们的怀疑之所以可能的基础,在此意义上,它们是确实性命题。但这并不意味着这些沉淀下来的东西具有永恒的真理性,具有绝对的确实性。并且,这些确实性命题无法被单独抽离来看,因为它们属于一个相互依赖的体系,属于一个统一的世界图景。由此,“维特根斯坦在这里最有力地抨击了笛卡儿以来认识论只顾追求某种‘完全确实’的东西这一错误方向” 。
由此,维特根斯坦消解了哲学家对绝对确信的信仰。自笛卡儿以来的对知识确定性的追求被宣布为无效。在此意义上,连同他们为知识确定性找到的保障(唯理论者斯宾诺莎的作为最高理性的上帝,经验论者洛克的感觉经验基础),都失去了意义。笛卡儿向人们指出的知识确定性能够给人以安全感,它令人们相信自己处于一栋十足稳固的知识大厦之中。而维特根斯坦让人们重新认识到,他们其实仍旧身处生活之河流中,这河流有的只是相对稳固的河床。
3康德对分析命题和综合命题的区分是无意义的
对知识确定性的消解,意味着康德对分析命题和综合命题的区分是无意义的。康德曾经这样区分分析命题和综合命题,即分析命题指像数学和逻辑命题那样相对于任何经验事实其值皆恒为真的命题,而综合命题则指像经验科学命题那样其值取决于经验事实的命题。而在维特根斯坦的河流比喻中,即便是分析命题,也仅仅只能充当暂时性的或者相对持久的河床。2*2=4并非像康德所认为的那样永恒真。“‘2*2=4’是一个正确的算术命题——不是‘在特殊场合下’,也不是‘永远’——但是说出的或写出的‘2*2=4’这个公式在中文中也许可以有一种不同的意义或者是完全无意义的胡说,由此可以看出这个命题只有在使用时才有意义。”维特根斯坦认为,并不存在独立于人和独立于人之计算学习的所谓计算本质。计算归根结底是一种使用,并且仅仅因人们的使用才慢慢硬化为语法规则。“我们是通过学习计算而得以知道计算的本质(Wesen)的。”“但是这样一来难道对于我们怎样确信计算的可靠性就不能加以描述了吗?噢,确实是这样。”“人们就是这样计算的。计算就是这样。这就是我们(比如说)在学校学会的东西。忘掉这种超验的确实性吧,因为它同你的精神的概念关联在一起。”“即使这次计算对我来说是已经确定的东西,这也仅仅是一种为了达到实用目的而采取的决定。”由此,计算首先服务于实用目的,而非自身绝对确实,在此意义上,根本不存在所谓绝对正确的“天赋观念”。而人们对永远可靠的计算和尚未确定的计算的区分,也只是“一种逻辑上的区别”——这就意味着,在本质上没有差别。它们都不绝对确实,而只是就人类共同体的语法规则而言具有相对的确实性。
奎因曾在其著名论文《经验论的两个教条》中提出相似观点。“他指出,在现实中,即便是一直以来被视为具有确定性的数学和逻辑命题,也存在着因其为伪命题而被合理地加以抛弃的情况;即便是经验科学命题,也可能存在无论在任何情况下都将其视为真而合理地继续加以使用的情况,因此,必然的分析命题与偶然的综合命题这两者间的界限,是流动不居的。” 奎因的这篇论文与维特根斯坦的《论确定性》大致完成于同一时期,其中观点也与《论确定性》有着惊人的相似。然而具有讽刺意味的却是,从60年代后期开始,维特根斯坦对英语圈哲学的影响出现了明显的衰落之势,而取而代之的正是奎因的哲学。
4知识、信念与谎言
基本信念还意味着,知识亦不过是一种信念。信念与知识对应的是同一种“心灵状态”(Seelenzustaende)。“认为与‘相信’和 ‘知道’这些词相对应的必然是些不同的心灵状态,这就好像人们相信与‘我’这个词和‘路德维希’这个名字相对应的因概念的不同而必然是不同的人一样。” (同上)一种“知道”既然以基本信念为前提,而基本信念又是没有根据的,那么知识归根结底也只是信念而已,同信念一样有其诞生和消灭,是有朽的。而信念之有朽意味着什么?尼采在其《敌基督者》一书中认为,信念与谎言并无实质差别。“每个信念都拥有其历史,拥有其原始形式、尝试阶段和错误:在它成为信念之前,它很长时间都不是信念,更长时间后几乎不可能成为信念。”“父亲所谓的谎言,在儿子那儿变成了信念。” 由此,信念打破了知识(真理)与谎言之间的严格对立:这世上本无所谓真理,信的人多了,就成了真理;这世上也本无所谓谎言,不信的人多了,就成了谎言。
海德格尔在《存在与时间》中揭示了此在的存在状态:此在往往在种种因缘际会中自以为“知”,却在所有因缘中断之时、在此在自身面前、在巨大的空无面前方觉出自己一无所知。此在“茫然失其所在” ,此在一头撞进空无。知背后隐藏的是一无所知,而此在一旦意识到自己一无所知,所知的一切就都立刻失去意义。作为因缘整体和意蕴结构的世界陷落,并开始变得无关紧要。不过,海德格尔对此在“畏”之状态的揭示,在维特根斯坦那里或许是无意义的。我们向来生活在人类共同体之中,对我们有意义的仅仅是这个共同体所习以为常的种种“知”,而我们根本无法追问超出共同体、超出日常用法的领域。“通常关于世界的实在性的断言实际上就是关于这样的世界的实在性的断言,通常所谓对于世界的认识也只是对于这样的世界的认识。至于独立于人们的概念框架或表现手段的(进而独立于人的)世界本身究竟是什么样子的,人们根本不可能知道(当然,这并不是说这样的世界不存在);甚至于,这样的问题根本没有任何意义。”
并且,维特根斯坦指出,不同的信念之间仍然存在区别。充当信念之流的河床或通道的基本信念,有的像岩石一般坚硬,有的则如同随时会被冲走的泥沙:“那条河流的岸边一部分是不发生变化或者变化小得令人察觉不到的坚硬的岩石,另一部分是随时随地被水冲走或者淤积下来的泥沙”。只不过,那些坚硬的岩石亦仅仅就河流而言,并非绝对真理。
从无根据的信念那里,尼采返回大地,海德格尔返回此在的存在本身,维特根斯坦返回人的日常生活。不同的是,在尼采那里,真正能做到返回大地的只有超人;在海德格尔那里,本真的向死存在始终作为一种可能性召唤人们痛下决心;而维特根斯坦所告诉人们的,仅仅是日常生活本身。他抵制了做形而上学家、做教导者的诱惑,而这诱惑对于古往今来的几乎所有哲学家来说,都似乎是无法抗拒的。
结论
在《论确实性》一书中,维特根斯坦指出了对摩尔对怀疑主义的反驳之不得要领,并进一步指出了怀疑主义者之怀疑在何种意义上才是不合法的。反对怀疑主义,并不意味着相信一种绝对确实性;恰恰相反,正是一种只具有相对确实性的基本信念体系、语言游戏规则、统一世界图景决定了彻底怀疑之不可能。维特根斯坦认为,这些无根据的基本信念来自人类共同体的生活,根据不同共同体的生活,可能形成不同的语言游戏、世界图景,但是却根本不存在哲学家所追求的所谓绝对真理。在此意义上,维特根斯坦的言说止于日常生活,而拒绝再做任何传统形而上学的演绎。
康德曾在其《纯粹理性批判》第二版序言中提到哲学和普遍人类理性的丑闻,即理性之无法真正反驳怀疑主义:“唯心论尽可以就形而上学的根本目的而言仍然被看作是无辜的,然而哲学和普遍人类理性的丑闻仍然存在,即不得不仅仅在信仰上假定在我们之外的物的存有,并且,如果有人忽然想到要怀疑这种存有,我们没有任何足够的证据能够反驳他” 。
针对这一丑闻,摩尔(George Edward Moore)在《外在世界的证明》(1939年)一文中做出了他的回答。摩尔认为他可以给出数量庞大的不同证明来反驳怀疑论者。“比如,我现在就可以证明存在两只手。如何证明呢?通过举起我的两只手,并且在我用右手做出某个手势时说‘这里有一只手’,而在用左手做出某个手势的时候补充‘这里还有另一只手’。” 摩尔继续说,如果这个证明成立,那么显然他还能举出更多其它证明。
但摩尔的这种证明显然不能让许多哲学家感到满意,因为摩尔并不能对“这里有一只手”和“这里还有另一只手”这些前提给出证明。摩尔对此说道: “虽然我不能对一些事情给出证明,但我仍然能够知道它们。”关于这一点,摩尔也曾在《为常识辩护》(1925年)一文中提到,存在一系列命题,“对于其中任何一个,我都确信地知道为真。”这一系列命题包括:“我有身体,它在过去某时出生,并且从那以后一直停留在地球附近”,“在三维空间中存在许多其它有形状大小的东西”,“除了我自己以外还有别人”,“地球在我出生之前很久就已存在”等等。
摩尔究竟有没有对怀疑主义做出有效的反驳?其对外在世界的证明是否有效?对此,维特根斯坦在《论确实性》一书中指出,摩尔对怀疑主义的反驳根本不得要领。摩尔并不知道怀疑主义者的怀疑在何种意义上是非法的,因此并不能对其做出有效的反驳。在维特根斯坦看来,怀疑论者对外在世界之存在的怀疑之所以不合法,原因并非在于外在世界确实存在,而在于他们的怀疑本身是有问题的。在此意义上,摩尔对于怀疑论者看似有力的正面回击,即证明外在世界如何的确存在,就成为不得要领的了。此外,摩尔用“我知道……”来证明外在世界的存在,恰恰暴露出他根本不知道“知道”一词的正确用法,而错将“知道”等同于一种绝对的确实性。
在《论确实性》这本书里,维特根斯坦认为,反对怀疑主义并不意味着支持绝对的确实性。恰恰相反,确实性只相对一种体系、世界图景、语言游戏而言,即任何命题的确实性只是相对的。即便是摩尔所举出的貌似无可反驳的命题,也只具有相对的确实性。因为关于外在世界,我们所拥有的至多不过是一些不可穷究其根据的基本信念。不过,对于这些信念我们虽然无法拥有绝对的确信,但亦无法怀疑,因为我们向来就生活在这些基本信念之中。只是在此意义上,怀疑主义才是无效的。
一、 摩尔不知道“知道”的正当用法
维特根斯坦指出,摩尔错误地使用了“知道”这个概念。摩尔认为,“知道”这一陈述“不可能是一种错误”。维特根斯坦指出,摩尔在这里忽视了 “知道”背后隐藏的“我相信我知道”的公式。“因为‘我知道’似乎是描述一种事态,这种事态保证所知的东西是一种事实,人们总是忘记‘我认为我知道’这个表达。”
在维特根斯坦那里,“知道”的正当用法如下:“‘我知道’经常表示这样的意思:我有正当的理由支持我说的语句”。而能够为某事提供正当理由并不意味着某事是绝对正确的,或言具有一种绝对的确实性,恰恰相反,具有正当理由意味着不具有正当理由情形,即“错误”的可能性。知识和错误是一对相伴相生的概念。凡我们所知道的东西,都有犯错的可能性。因为“说出‘我知道’这种保证是不够的,因为我不可能弄错毕竟只是一种保证,而在那件事上我不可能弄错却需要在客观上加以证实”。
这也意味着,“知道”和“出错”的使用是有界限的。维特根斯坦认为,对于一些无法用真假对错去评判的、关涉生活世界基础的基本信念,我们无法说“我知道”或“出错了”。“知道”所处的是日常的体系内部的因果链条,它在体系内部中可以进行有效的运作;但是对于那些规定了体系本身、规定了世界和语言界限的基本命题,我们可做的只有相信。一个人可以有效地计算,但是却无法为计算的确实性找到绝对的证明,因为一切诸如“这是老师教我的”之类的解释最终会走到尽头:“如果有人教某个人学计算,那么是否也要教他:他能够依靠他老师的计算?但是这些说明到时候毕竟会走到尽头”,“难道验证不是终有个完结吗?”。在穷尽处,即基本信念领域,我们不可再问根据,而只需相信。
二、关于基本信念、确实性和世界图景
这些基本命题或基本信念首先包括,比如摩尔所说的“我有一只手”,或者“我是一个人”、“我有大脑”“地球在我出生之前很久就已存在”等等。对于这些命题,既无法说真,亦无法说假。而之所以如此,其中理由并不在于怀疑论者所提出的感觉经验的可骗性,或是摩尔提出的常识辩护,而仅仅在于,这些命题是我们生活中的基本信念,它们构成了其它信念之所以可能的基础。一般情况下,对于这些命题既无法谈“知道”,亦无法谈“出错”。在此意义上,这些命题是不可怀疑的。在这些基本信念上出问题,关涉的不是错误,而是精神问题。“如果我的朋友有一天想像他在某某地方已经住了很长一段时间,等等,等等,我不会把这件事叫做错误,而是叫做精神失常,也许是暂时性的精神失常。”以此类推,没有特殊理由的不知道他有一只手或他是一个人,也只能被归于精神失常。
这些基本信念来源于人们的生活共同体,来自人们习以为常、约定俗成的使用,来自“没有理由的行动方式”。由于这些信念规定了我们日常生活的基本框架,所以它们的反面在通常情况下是不可想象的。“表达摩尔所‘知道’的事物的命题都属于这样一类命题,即很难想像一个人为什么应当相信其反面。例如那个讲摩尔已经贴近地球生活了一辈子的命题。……我看到的和听到的所有事物都让我确信没有人曾远离地球。在我的世界图景中没有一件事物支持其反面的说法。” 这些命题是“一切思想(语言)运作的基础”,是“我们思想的框架”,是“我一切行动的基础”,以故,虽然维特根斯坦批评摩尔采取了错误的方式去维护常识,但摩尔的维护常识的态度的确为维特根斯坦所赞同。“维特根斯坦相信摩尔所列举的命题的程度绝不亚于摩尔本人。”
当然,这并不意味着这些命题具有自明的绝对的确实性,而只是因为既然我们处于共同体之中,我们便没有理由不相信,也不可能不相信。这些基本信念既然来自人类生活共同体,就必定是历史性的,有诞生有消灭。一些在这代人那里曾经是基本信念的,到了下代人就不一定还是基本信念。在此,维特根斯坦有一个极为生动的比喻,他将生活比作河流,而将基本信念比作通道或河床:“可以想像,一些经验命题得以凝结,对其后来凝结的,仍然是有流动性的命题起到作为通道的作用;也可以想像,随着时间的推移,上述关系将发生变化:曾经具有流动性的命题获知凝结,而曾经凝结了的命题,变得具有流动性”。“这种神话可能变为原来的流动状态,思想的河床可能移动。”
在维特根斯坦那里,并不存在绝对的确实性,确实性仅仅具有相对的含义,仅仅针对某一民族某一阶段的生活而言。在此意义上,确实性只是虚的东西:“确实性就像是一种语气,人们用这种语气肯定事态,但是人们并不是从语气中推导出这样说就有道理”。确信并不是推理的基础,而只是所有推理之可能进行的前提。依靠这种虚的确定性,人们才能建立起所有一般信念,并在其中做有效的推理。海德格尔也曾经向我们揭示出“虚”的重要性。他指出我们的文化往往并非关注实的东西,那些由实的东西承载的虚的东西才是关键。此在的意义在于虚的东西。种种虚的指引让人烦劳操心,虚的时间性结构是此在的本质结构。维特根斯坦和海德格尔在很多方面不一致,但却不约而同地指出了如下一点,即:人们往往刻意地努力去追求实在,却不知自己总已处身于虚之中。
而仅仅具有相对确实性的基本信念必定总已处于一个体系之中。在信念之流之中,河床的沉积或者被冲刷与流水相关。没有任何一个命题具有绝对的确定性,意味着没有任何一个命题能够被单独抽离来看——所有命题都属于一个相互依赖的体系。“某些经验命题的真实性(Wahrheit)属于我们的参照系(Bezugssystem)。”“使我认为明显无误的并不是一些单独的公理,而是一个前提与结论互相支持的体系。”“某个信念之所以占有稳固的地位,与其说是由于其本身显而易见或令人信服,倒不如说是靠其周围的信念才使它不可动摇。”“有关一种假设的一切检验、一切证实或否证都早已发生在一个体系之中。这个体系并不是我们进行一切论证时所采用的多少带有任意性或者不太可靠的出发点,而是属于我们称之为论证的本质。这个体系与其说是论证的出发点,不如说是赋予论证以生命的活力。”这个体系自身并不绝对确实,但是却构成相应人群生活的统一背景,是一切论证和检验可以生效的前提。换言之,这个体系是一个共同体的世界图景。对此维特根斯坦说道:“我有一个世界图景。这个世界图景是真还是假?最重要的在于它是我的一切探讨和断言的基础。那些描述它的命题并不是全都同样受到检验的制约。”
不同时代有着几乎完全不同的世界图景。在古希腊人那里,他们的祖先和奥林匹亚诸神以各种方式渗透了他们的生活;在中世纪的欧洲,上帝是最高的实在,存在地上之城和上帝之城两个世界;而在不信神的现代人眼前展现的,则是科学的客观的世界图景。即便是在同一时代,不同地域人们的世界图景亦有天差地别,比如当今美国人民与非洲某原始部落之世界图景的差别。甚至即便是在同一时代、同一地域的人们,也有可能拥有彼此相异的世界图景,比如基督徒与无神论者。在自然环境、社会、以及各种偶然因素的影响下,人们从各自的实践中沉淀出属于自己种群的独特的世界图景。而不同的世界图景意味着不同的基本信念体系,意味着不同的语法规则,并在此意义上无所谓优劣差等。身处某一世界图景之中的人们总是以自己的世界观为正确,并力图让处于其外的人们也接受它。维特根斯坦将这种世界图景等同于一种积极意义上的神话:“描述这幅世界图景的命题也许是一种神话的一部分,其功用类似于一种游戏的规则。这种游戏可从全靠实践而不是靠任何明确的规则学会。”
三、基本信念说意味着什么
1怀疑主义者的怀疑是非法的
维特根斯坦反对怀疑主义,但他的反对并非出于对绝对确实性的相信——像摩尔所以为的那样。维特根斯坦只承认一种相对的确定性,但相对的确定性将并不导致怀疑主义,而恰恰将揭示出,怀疑论者所说的怀疑是没有意义的。我们向来总已生活在一个统一背景之中,基本信念规定了我们思想和语言的框架,在此意义上,要想进行彻底怀疑是根本不可能的。“如果你想怀疑一切,你就什么也不能怀疑。怀疑这种游戏本身就预先假定了确实性。”“如果你什么事实也不确知,那么你也就不能确知你所用的词的意义。”“怀疑出现在信念之后。”“我知道”是怀疑之可能的基础。若不能说“我知道”,就不能说“我怀疑”。“对于一种存在的怀疑只能在一种语言游戏中进行。”“一种怀疑一切的怀疑就不成其为怀疑。”“这表明不容怀疑属于语言游戏的本质”,而语言游戏归根结底乃是一种生活形式,“因为行动才是语言游戏的根基”。“我们不怀疑所有这些事实只是我们的判断方式,因而也就是我们的行为方式。”
事实上,康德所说的“哲学和普遍人类理性的丑闻”直接来自休谟的怀疑论。而维特根斯坦之所以能够成功地抵制休谟的怀疑论,其原因恰恰在于维特根斯坦在一定程度上承认了休谟的前提,即因果关系本不是必然的,我们日常以为真的只是些暂时固定下来的信念,并不必然真。但是,正是在此意义上,跳出基本信念的圈子去绝对怀疑才是不可能的。人无法离开生活之流而在地面上进行观察,因为这样的地面根本就不存在。而摩尔对怀疑主义不恰当的反驳透露出,摩尔其实既不知道“知道”,也不知道“怀疑”。
2自笛卡儿以来的对知识确定性的追求被宣布为无效
在《第一哲学沉思集》中,笛卡儿致力于通过彻底怀疑找出人类知识的最后支点,即我们能够绝对确信的东西:“我思故我在”。笛卡儿相信由此他便可以重建人类知识大厦,并最终克服怀疑主义。而在维特根斯坦看来,根本上说,是因为笛卡儿非法地使用了怀疑概念,才构建出所谓绝对确信的东西。而事实是,我们始终在生活的河流之中,所能触及的只能是暂时或者相对持久地沉积下来的河床。我们无法怀疑这些沉淀下来的东西,因为它们是我们的怀疑之所以可能的基础,在此意义上,它们是确实性命题。但这并不意味着这些沉淀下来的东西具有永恒的真理性,具有绝对的确实性。并且,这些确实性命题无法被单独抽离来看,因为它们属于一个相互依赖的体系,属于一个统一的世界图景。由此,“维特根斯坦在这里最有力地抨击了笛卡儿以来认识论只顾追求某种‘完全确实’的东西这一错误方向” 。
由此,维特根斯坦消解了哲学家对绝对确信的信仰。自笛卡儿以来的对知识确定性的追求被宣布为无效。在此意义上,连同他们为知识确定性找到的保障(唯理论者斯宾诺莎的作为最高理性的上帝,经验论者洛克的感觉经验基础),都失去了意义。笛卡儿向人们指出的知识确定性能够给人以安全感,它令人们相信自己处于一栋十足稳固的知识大厦之中。而维特根斯坦让人们重新认识到,他们其实仍旧身处生活之河流中,这河流有的只是相对稳固的河床。
3康德对分析命题和综合命题的区分是无意义的
对知识确定性的消解,意味着康德对分析命题和综合命题的区分是无意义的。康德曾经这样区分分析命题和综合命题,即分析命题指像数学和逻辑命题那样相对于任何经验事实其值皆恒为真的命题,而综合命题则指像经验科学命题那样其值取决于经验事实的命题。而在维特根斯坦的河流比喻中,即便是分析命题,也仅仅只能充当暂时性的或者相对持久的河床。2*2=4并非像康德所认为的那样永恒真。“‘2*2=4’是一个正确的算术命题——不是‘在特殊场合下’,也不是‘永远’——但是说出的或写出的‘2*2=4’这个公式在中文中也许可以有一种不同的意义或者是完全无意义的胡说,由此可以看出这个命题只有在使用时才有意义。”维特根斯坦认为,并不存在独立于人和独立于人之计算学习的所谓计算本质。计算归根结底是一种使用,并且仅仅因人们的使用才慢慢硬化为语法规则。“我们是通过学习计算而得以知道计算的本质(Wesen)的。”“但是这样一来难道对于我们怎样确信计算的可靠性就不能加以描述了吗?噢,确实是这样。”“人们就是这样计算的。计算就是这样。这就是我们(比如说)在学校学会的东西。忘掉这种超验的确实性吧,因为它同你的精神的概念关联在一起。”“即使这次计算对我来说是已经确定的东西,这也仅仅是一种为了达到实用目的而采取的决定。”由此,计算首先服务于实用目的,而非自身绝对确实,在此意义上,根本不存在所谓绝对正确的“天赋观念”。而人们对永远可靠的计算和尚未确定的计算的区分,也只是“一种逻辑上的区别”——这就意味着,在本质上没有差别。它们都不绝对确实,而只是就人类共同体的语法规则而言具有相对的确实性。
奎因曾在其著名论文《经验论的两个教条》中提出相似观点。“他指出,在现实中,即便是一直以来被视为具有确定性的数学和逻辑命题,也存在着因其为伪命题而被合理地加以抛弃的情况;即便是经验科学命题,也可能存在无论在任何情况下都将其视为真而合理地继续加以使用的情况,因此,必然的分析命题与偶然的综合命题这两者间的界限,是流动不居的。” 奎因的这篇论文与维特根斯坦的《论确定性》大致完成于同一时期,其中观点也与《论确定性》有着惊人的相似。然而具有讽刺意味的却是,从60年代后期开始,维特根斯坦对英语圈哲学的影响出现了明显的衰落之势,而取而代之的正是奎因的哲学。
4知识、信念与谎言
基本信念还意味着,知识亦不过是一种信念。信念与知识对应的是同一种“心灵状态”(Seelenzustaende)。“认为与‘相信’和 ‘知道’这些词相对应的必然是些不同的心灵状态,这就好像人们相信与‘我’这个词和‘路德维希’这个名字相对应的因概念的不同而必然是不同的人一样。” (同上)一种“知道”既然以基本信念为前提,而基本信念又是没有根据的,那么知识归根结底也只是信念而已,同信念一样有其诞生和消灭,是有朽的。而信念之有朽意味着什么?尼采在其《敌基督者》一书中认为,信念与谎言并无实质差别。“每个信念都拥有其历史,拥有其原始形式、尝试阶段和错误:在它成为信念之前,它很长时间都不是信念,更长时间后几乎不可能成为信念。”“父亲所谓的谎言,在儿子那儿变成了信念。” 由此,信念打破了知识(真理)与谎言之间的严格对立:这世上本无所谓真理,信的人多了,就成了真理;这世上也本无所谓谎言,不信的人多了,就成了谎言。
海德格尔在《存在与时间》中揭示了此在的存在状态:此在往往在种种因缘际会中自以为“知”,却在所有因缘中断之时、在此在自身面前、在巨大的空无面前方觉出自己一无所知。此在“茫然失其所在” ,此在一头撞进空无。知背后隐藏的是一无所知,而此在一旦意识到自己一无所知,所知的一切就都立刻失去意义。作为因缘整体和意蕴结构的世界陷落,并开始变得无关紧要。不过,海德格尔对此在“畏”之状态的揭示,在维特根斯坦那里或许是无意义的。我们向来生活在人类共同体之中,对我们有意义的仅仅是这个共同体所习以为常的种种“知”,而我们根本无法追问超出共同体、超出日常用法的领域。“通常关于世界的实在性的断言实际上就是关于这样的世界的实在性的断言,通常所谓对于世界的认识也只是对于这样的世界的认识。至于独立于人们的概念框架或表现手段的(进而独立于人的)世界本身究竟是什么样子的,人们根本不可能知道(当然,这并不是说这样的世界不存在);甚至于,这样的问题根本没有任何意义。”
并且,维特根斯坦指出,不同的信念之间仍然存在区别。充当信念之流的河床或通道的基本信念,有的像岩石一般坚硬,有的则如同随时会被冲走的泥沙:“那条河流的岸边一部分是不发生变化或者变化小得令人察觉不到的坚硬的岩石,另一部分是随时随地被水冲走或者淤积下来的泥沙”。只不过,那些坚硬的岩石亦仅仅就河流而言,并非绝对真理。
从无根据的信念那里,尼采返回大地,海德格尔返回此在的存在本身,维特根斯坦返回人的日常生活。不同的是,在尼采那里,真正能做到返回大地的只有超人;在海德格尔那里,本真的向死存在始终作为一种可能性召唤人们痛下决心;而维特根斯坦所告诉人们的,仅仅是日常生活本身。他抵制了做形而上学家、做教导者的诱惑,而这诱惑对于古往今来的几乎所有哲学家来说,都似乎是无法抗拒的。
结论
在《论确实性》一书中,维特根斯坦指出了对摩尔对怀疑主义的反驳之不得要领,并进一步指出了怀疑主义者之怀疑在何种意义上才是不合法的。反对怀疑主义,并不意味着相信一种绝对确实性;恰恰相反,正是一种只具有相对确实性的基本信念体系、语言游戏规则、统一世界图景决定了彻底怀疑之不可能。维特根斯坦认为,这些无根据的基本信念来自人类共同体的生活,根据不同共同体的生活,可能形成不同的语言游戏、世界图景,但是却根本不存在哲学家所追求的所谓绝对真理。在此意义上,维特根斯坦的言说止于日常生活,而拒绝再做任何传统形而上学的演绎。
Monday, October 18, 2010
内存杂碎
编译时分配内存 ---------------
楼上说的对的,编译时是不分配内存的。此时只是根据声明时的类型进行占位,到以后程序执行时分配内存才会正确。所以声明是给编译器看的,聪明的编译器能根据声明帮你识别错误。
运行时分配内存 ---------------
这是对的,运行时程序是必须调到“内存”的。因为CPU(其中有多个寄存器)只与内存打交道的。程序在进入实际内存之前要首先分配物理内存。
编译过程 --------------
只能简单说一下,因为如果要详细的话,就是一本书了《编译原理》。编译器能够识别语法,数据类型等等。然后逐行逐句检查编译成二进制数据的obj文件,然后再由链接程序将其链接成一个EXE文件。此时的程序是以EXE文件的形式存放在磁盘上。
运行过程 --------------
当执行这个EXE文件以后,此程序就被加载到内存中,成为进程。此时一开始程序会初始化一些全局对象,然后找到入口函数(main()或者WinMain()),就开始按程序的执行语句开始执行。此时需要的内存只能在程序的堆上进行动态增加/释放了。
--http://zhidao.baidu.com/question/41868474.html?fr=qrl&cid=866&index=1&fr2=query
编译其实只是一个扫描过程,进行词法语法检查,代码优化而已,编译程序越好,程序运行的时候越高效。 我想你说的“编译时分配内存”是指“编译时赋初值”,它只是形成一个文本,检查无错误,并没有分配内存空间。 当你运行时,系统才把程序导入内存。一个进程(即运行中的程序)在主要包括以下五个分区: 栈、堆、bss、data、code 代码(编译后的二进制代码)放在code区,代码中生成的各种变量、常量按不同类型分别存放在其它四个区。系统依照代码顺序执行,然后依照代码方案改变或调用数据,这就是一个程序的运行过程。
--http://zhidao.baidu.com/question/41868474.html?fr=qrl&cid=866&index=1&fr2=query
我对于C++动态绑定的理解,一句话,就是编译器用静态分析的方法加上虚拟函数的设计实现在程序运行时动态 智能执行正确虚拟函数的技术。因此要彻底理解动态绑定技术,只需要掌握两点,一是编译器的静态编译过程,二是 虚拟函数的基本知识。只要有了这两点理解,任何动态绑定的分析都是很容易的。 下面就以例子代码说明:
#include
using namespace std;
class A
...{
public:
void fA() ...{ cout << "A::fA()" << endl; }
virtual void vfA() ...{ cout << "A::vfA()" << endl; }
void emptyB() ...{ cout << "A::emptyB()" << endl; }
void vfAonly() ...{ cout << "A::vfAonly()" << endl; }
};
class B : public A
...{
public:
void fB() ...{ cout << "B::fB()" << endl; }
virtual void vfA() ...{ cout << "B::vfA()" << endl; }
virtual void vfB() ...{ cout << "B::vfB()" << endl; }
void emptyA() ...{ cout << "B::emptyA()" << endl; }
virtual void vfAonly() ...{ cout << "B::vfAonly()" << endl; }
};
int main()
...{
A* p = new B;
B& r = *(B*)p;
p->fA(); // 1
//p->fB(); // 2
p->vfA(); // 3
//p->vfB(); // 4
//p->emptyA(); // 5
p->emptyB(); // 6
p->vfAonly(); // 7
cout << endl;
r.fA(); // 8
r.fB(); // 9
r.vfA(); // 10
r.vfB(); // 11
r.emptyA(); // 12
r.emptyB(); // 13
r.vfAonly(); // 14
delete p;
return 0;
}
输出结果:
A::fA()
B::vfA()
A::emptyB()
A::vfAonly()
A::fA()
B::fB()
B::vfA()
B::vfB()
B::emptyA()
A::emptyB()
B::vfAonly()
分析: 我们通过模拟编译器的编译过程来进行解释。只看编译器是怎么编译带有标号的那些函数调用的行的。 行1. 在编译器眼中,p就是一个纯粹的A类指针,跟他指向的B类对象没有任何联系。因此,当看到 p->fA()时,编译器便去A的定义中寻找fA,找到了,于是生成调用代码。 行2. 这行如果不被注释,编译器去A的定义中寻找定义fB,但是找不到这个名字,便会输出错误信息。 行3. 编译器继续去A定义中寻找vfA,这次找到了,而且发现关键字virtual,于是,采用虚拟函数调用 代码生成技术,根据vfA的偏移值,生成代码调用虚拟函数表中该偏移值指向的函数。特别指出的 是,在静态编译期间,编译器只知道偏移值,并不知道运行时该偏移到底指向什么函数。实际效果 是,因为运行时,p指向的是B对象,因此调用的是B的虚拟函数vfA(). 行4. 这行如果不被注释,编译器去A的定义中寻找名字vfB,找不到,出错。记住第一条原则,编译器 是静态编译,不知道p和类B有联系。 行5. 同4,找不到名字emptyA。 行6. 简单,找到名字emptyB. 行7. 简单,找到名字vfAonly。 行8. 从这里开始,函数由B类引用r调用。在编译器眼中,r就是一个纯粹的B类引用,他不假设r和A有任何 关系。因此这一行,编译器去B类定义寻找名字fA。由于B继承自A,包括所有A的public函数定义, 编译器成功找到A::fA。 行9. 类似行8,找到B自身的函数定义fB。 行10. 类似行3,编译器生成代码调用虚拟函数表某偏移指向的函数。运行时该偏移指向B::vfA. 行11. 编译器生成代码调用虚拟函数表某偏移指向的函数。运行时该偏移指向B::vfB. 行12. 简单,找到名字emptyA. 行13. 简单,找到名字A::emptyB. 因为B继承自A。 行14. 编译器生成代码调用虚拟函数表某偏移指向的函数。运行时该偏移指向B::vfAonly. 为什么编译器知道 指向的是B的虚拟函数vfAonly而不是A的非虚拟函数呢?这跟另一个静态编译规则,名字隐藏,有关。 继承类的作用域中如果有基类的同名函数,继承类中的名字将隐藏基类同名函数,因此这时,编译器看 不见A::vfAonly--http://zhidao.baidu.com/question/36832319.html?si=1
所谓绑定是指,对于参与多态行为的类型,他们具有多态行为的接口是在公共基类的设计中就预先确定的。而非绑定则对于参与多态行为的类型,他们的接口没有预先定义。 在C++中通过继承实现的多态是动态绑定,通过模板实现的多态是静态绑定。动态绑定的接口是在运行期间(动态)完成的,静态绑定的接口是在编译期间(静态)完成的 --http://zhidao.baidu.com/question/16751113.html?si=5
在计算机领域,堆栈是一个不容忽视的概念,但是很多人甚至是计算机专业的人也没有明确堆栈其实是两种数据结构。
要点:
堆:顺序随意
栈:先进后出
堆和栈的区别
一、预备知识—程序的内存分配
一个由c/C++编译的程序占用的内存分为以下几个部分
1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放(就会造成内存泄漏的问题),程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。
3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域(data), 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域(BSS,Block Started by Symbol)。 - 程序结束后有系统释放(在整个程序的执行过程中都是有效的)
4、文字常量区 —常量字符串就是放在这里的。 程序结束后由系统释放 (文字常量区内的数据可以修改吗?)
5、程序代码区(code)—存放函数体的二进制代码。
二、例子程序
这是一个前辈写的,非常详细
//main.cpp
int a = 0; 全局初始化区
char *p1; 全局未初始化区
main()
{
int b; 栈
char s[] = "abc"; 栈 //abc是在栈里面,而下面的123456\0却在在常量区内,要注意这两种情况的区别
char *p2; 栈
char *p3 = "123456"; 123456\0在常量区,p3在栈上。
static int c =0; 全局(静态)初始化区
p1 = (char *)malloc(10);
p2 = (char *)malloc(20);
分配得来得10和20字节的区域就在堆区。
strcpy(p1, "123456"); 123456\0放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。 (所谓的优化是什么意思,是指P1和P2指向的是同一块内存吗?)
}
二、堆和栈的理论知识
2.1申请方式
stack:
由系统自动分配。 例如,声明在函数中一个局部变量 int b; 系统自动在栈中为b开辟空间
heap:
需要程序员自己申请,并指明大小,在c中malloc函数
如p1 = (char *)malloc(10);
在C++中用new运算符
如p2 = (char *)malloc(10);
但是注意p1、p2本身是在栈中的。
2.2 申请后系统的响应
栈:只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。
堆:首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,
会 遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内 存空间中的首地址处记录本次分配的大小,这样,代码中的delete语句才能正确的释放本内存空间。另外,由于找到的堆结点的大小不一定正好等于申请的大 小,系统会自动的将多余的那部分重新放入空闲链表中。
2.3申请大小的限制
栈:在Windows下,栈是向低地址扩展的数 据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在 WINDOWS下,栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因 此,能从栈获得的空间较小。
堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。
2.4申请效率的比较:
栈由系统自动分配,速度较快。但程序员是无法控制的。
堆是由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便.
另外,在WINDOWS下,最好的方式是用VirtualAlloc分配内存,他不是在堆,也不是在栈是直接在进程的地址空间中保留一快内存,虽然用起来最不方便。但是速度快,也最灵活
2.5堆和栈中的存储内容
栈: 在函数调用时,第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由 右往左入栈的,然后是函数中的局部变量。注意静态变量是不入栈的。 当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。
堆:一般是在堆的头部用一个字节存放堆的大小。堆中的具体内容有程序员安排。
2.6存取效率的比较
char s1[] = "aaaaaaaaaaaaaaa";
char *s2 = "bbbbbbbbbbbbbbbbb";
aaaaaaaaaaa是在运行时刻赋值的;
而bbbbbbbbbbb是在编译时就确定的;
但是,在以后的存取中,在栈上的数组比指针所指向的字符串(例如堆)快。
比如:
#include
void main()
{
char a = 1;
char c[] = "1234567890";
char *p ="1234567890";
a = c[1];
a = p[1];
return;
}
对应的汇编代码
10: a = c[1];
00401067 8A 4D F1 mov cl,byte ptr [ebp-0Fh]
0040106A 88 4D FC mov byte ptr [ebp-4],cl
11: a = p[1];
0040106D 8B 55 EC mov edx,dword ptr [ebp-14h]
00401070 8A 42 01 mov al,byte ptr [edx+1]
00401073 88 45 FC mov byte ptr [ebp-4],al
第一种在读取时直接就把字符串中的元素读到寄存器cl中,而第二种则要先把指针值读到edx中,在根据edx读取字符,显然慢了。
2.7小结:
堆和栈的区别可以用如下的比喻来看出:
使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗
菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。
使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。
堆和栈的区别主要分:
操作系统方面的堆和栈,如上面说的那些,不多说了。
还有就是数据结构方面的堆和栈,这些都是不同的概念。这里的堆实际上指的就是(满足堆性质的)优先队列的一种数据结构,第1个元素有最高的优先权;栈实际上就是满足先进后出的性质的数学或数据结构。
虽然堆栈,堆栈的说法是连起来叫,但是他们还是有很大区别的,连着叫只是由于历史的原因。
----http://blog.csdn.net/yulaotou/archive/2009/09/21/4577879.aspx
楼上说的对的,编译时是不分配内存的。此时只是根据声明时的类型进行占位,到以后程序执行时分配内存才会正确。所以声明是给编译器看的,聪明的编译器能根据声明帮你识别错误。
运行时分配内存 ---------------
这是对的,运行时程序是必须调到“内存”的。因为CPU(其中有多个寄存器)只与内存打交道的。程序在进入实际内存之前要首先分配物理内存。
编译过程 --------------
只能简单说一下,因为如果要详细的话,就是一本书了《编译原理》。编译器能够识别语法,数据类型等等。然后逐行逐句检查编译成二进制数据的obj文件,然后再由链接程序将其链接成一个EXE文件。此时的程序是以EXE文件的形式存放在磁盘上。
运行过程 --------------
当执行这个EXE文件以后,此程序就被加载到内存中,成为进程。此时一开始程序会初始化一些全局对象,然后找到入口函数(main()或者WinMain()),就开始按程序的执行语句开始执行。此时需要的内存只能在程序的堆上进行动态增加/释放了。
--http://zhidao.baidu.com/question/41868474.html?fr=qrl&cid=866&index=1&fr2=query
编译其实只是一个扫描过程,进行词法语法检查,代码优化而已,编译程序越好,程序运行的时候越高效。 我想你说的“编译时分配内存”是指“编译时赋初值”,它只是形成一个文本,检查无错误,并没有分配内存空间。 当你运行时,系统才把程序导入内存。一个进程(即运行中的程序)在主要包括以下五个分区: 栈、堆、bss、data、code 代码(编译后的二进制代码)放在code区,代码中生成的各种变量、常量按不同类型分别存放在其它四个区。系统依照代码顺序执行,然后依照代码方案改变或调用数据,这就是一个程序的运行过程。
--http://zhidao.baidu.com/question/41868474.html?fr=qrl&cid=866&index=1&fr2=query
我对于C++动态绑定的理解,一句话,就是编译器用静态分析的方法加上虚拟函数的设计实现在程序运行时动态 智能执行正确虚拟函数的技术。因此要彻底理解动态绑定技术,只需要掌握两点,一是编译器的静态编译过程,二是 虚拟函数的基本知识。只要有了这两点理解,任何动态绑定的分析都是很容易的。 下面就以例子代码说明:
#include
using namespace std;
class A
...{
public:
void fA() ...{ cout << "A::fA()" << endl; }
virtual void vfA() ...{ cout << "A::vfA()" << endl; }
void emptyB() ...{ cout << "A::emptyB()" << endl; }
void vfAonly() ...{ cout << "A::vfAonly()" << endl; }
};
class B : public A
...{
public:
void fB() ...{ cout << "B::fB()" << endl; }
virtual void vfA() ...{ cout << "B::vfA()" << endl; }
virtual void vfB() ...{ cout << "B::vfB()" << endl; }
void emptyA() ...{ cout << "B::emptyA()" << endl; }
virtual void vfAonly() ...{ cout << "B::vfAonly()" << endl; }
};
int main()
...{
A* p = new B;
B& r = *(B*)p;
p->fA(); // 1
//p->fB(); // 2
p->vfA(); // 3
//p->vfB(); // 4
//p->emptyA(); // 5
p->emptyB(); // 6
p->vfAonly(); // 7
cout << endl;
r.fA(); // 8
r.fB(); // 9
r.vfA(); // 10
r.vfB(); // 11
r.emptyA(); // 12
r.emptyB(); // 13
r.vfAonly(); // 14
delete p;
return 0;
}
输出结果:
A::fA()
B::vfA()
A::emptyB()
A::vfAonly()
A::fA()
B::fB()
B::vfA()
B::vfB()
B::emptyA()
A::emptyB()
B::vfAonly()
分析: 我们通过模拟编译器的编译过程来进行解释。只看编译器是怎么编译带有标号的那些函数调用的行的。 行1. 在编译器眼中,p就是一个纯粹的A类指针,跟他指向的B类对象没有任何联系。因此,当看到 p->fA()时,编译器便去A的定义中寻找fA,找到了,于是生成调用代码。 行2. 这行如果不被注释,编译器去A的定义中寻找定义fB,但是找不到这个名字,便会输出错误信息。 行3. 编译器继续去A定义中寻找vfA,这次找到了,而且发现关键字virtual,于是,采用虚拟函数调用 代码生成技术,根据vfA的偏移值,生成代码调用虚拟函数表中该偏移值指向的函数。特别指出的 是,在静态编译期间,编译器只知道偏移值,并不知道运行时该偏移到底指向什么函数。实际效果 是,因为运行时,p指向的是B对象,因此调用的是B的虚拟函数vfA(). 行4. 这行如果不被注释,编译器去A的定义中寻找名字vfB,找不到,出错。记住第一条原则,编译器 是静态编译,不知道p和类B有联系。 行5. 同4,找不到名字emptyA。 行6. 简单,找到名字emptyB. 行7. 简单,找到名字vfAonly。 行8. 从这里开始,函数由B类引用r调用。在编译器眼中,r就是一个纯粹的B类引用,他不假设r和A有任何 关系。因此这一行,编译器去B类定义寻找名字fA。由于B继承自A,包括所有A的public函数定义, 编译器成功找到A::fA。 行9. 类似行8,找到B自身的函数定义fB。 行10. 类似行3,编译器生成代码调用虚拟函数表某偏移指向的函数。运行时该偏移指向B::vfA. 行11. 编译器生成代码调用虚拟函数表某偏移指向的函数。运行时该偏移指向B::vfB. 行12. 简单,找到名字emptyA. 行13. 简单,找到名字A::emptyB. 因为B继承自A。 行14. 编译器生成代码调用虚拟函数表某偏移指向的函数。运行时该偏移指向B::vfAonly. 为什么编译器知道 指向的是B的虚拟函数vfAonly而不是A的非虚拟函数呢?这跟另一个静态编译规则,名字隐藏,有关。 继承类的作用域中如果有基类的同名函数,继承类中的名字将隐藏基类同名函数,因此这时,编译器看 不见A::vfAonly--http://zhidao.baidu.com/question/36832319.html?si=1
所谓绑定是指,对于参与多态行为的类型,他们具有多态行为的接口是在公共基类的设计中就预先确定的。而非绑定则对于参与多态行为的类型,他们的接口没有预先定义。 在C++中通过继承实现的多态是动态绑定,通过模板实现的多态是静态绑定。动态绑定的接口是在运行期间(动态)完成的,静态绑定的接口是在编译期间(静态)完成的 --http://zhidao.baidu.com/question/16751113.html?si=5
在计算机领域,堆栈是一个不容忽视的概念,但是很多人甚至是计算机专业的人也没有明确堆栈其实是两种数据结构。
要点:
堆:顺序随意
栈:先进后出
堆和栈的区别
一、预备知识—程序的内存分配
一个由c/C++编译的程序占用的内存分为以下几个部分
1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放(就会造成内存泄漏的问题),程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。
3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域(data), 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域(BSS,Block Started by Symbol)。 - 程序结束后有系统释放(在整个程序的执行过程中都是有效的)
4、文字常量区 —常量字符串就是放在这里的。 程序结束后由系统释放 (文字常量区内的数据可以修改吗?)
5、程序代码区(code)—存放函数体的二进制代码。
二、例子程序
这是一个前辈写的,非常详细
//main.cpp
int a = 0; 全局初始化区
char *p1; 全局未初始化区
main()
{
int b; 栈
char s[] = "abc"; 栈 //abc是在栈里面,而下面的123456\0却在在常量区内,要注意这两种情况的区别
char *p2; 栈
char *p3 = "123456"; 123456\0在常量区,p3在栈上。
static int c =0; 全局(静态)初始化区
p1 = (char *)malloc(10);
p2 = (char *)malloc(20);
分配得来得10和20字节的区域就在堆区。
strcpy(p1, "123456"); 123456\0放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。 (所谓的优化是什么意思,是指P1和P2指向的是同一块内存吗?)
}
二、堆和栈的理论知识
2.1申请方式
stack:
由系统自动分配。 例如,声明在函数中一个局部变量 int b; 系统自动在栈中为b开辟空间
heap:
需要程序员自己申请,并指明大小,在c中malloc函数
如p1 = (char *)malloc(10);
在C++中用new运算符
如p2 = (char *)malloc(10);
但是注意p1、p2本身是在栈中的。
2.2 申请后系统的响应
栈:只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。
堆:首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,
会 遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内 存空间中的首地址处记录本次分配的大小,这样,代码中的delete语句才能正确的释放本内存空间。另外,由于找到的堆结点的大小不一定正好等于申请的大 小,系统会自动的将多余的那部分重新放入空闲链表中。
2.3申请大小的限制
栈:在Windows下,栈是向低地址扩展的数 据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在 WINDOWS下,栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因 此,能从栈获得的空间较小。
堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。
2.4申请效率的比较:
栈由系统自动分配,速度较快。但程序员是无法控制的。
堆是由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便.
另外,在WINDOWS下,最好的方式是用VirtualAlloc分配内存,他不是在堆,也不是在栈是直接在进程的地址空间中保留一快内存,虽然用起来最不方便。但是速度快,也最灵活
2.5堆和栈中的存储内容
栈: 在函数调用时,第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由 右往左入栈的,然后是函数中的局部变量。注意静态变量是不入栈的。 当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。
堆:一般是在堆的头部用一个字节存放堆的大小。堆中的具体内容有程序员安排。
2.6存取效率的比较
char s1[] = "aaaaaaaaaaaaaaa";
char *s2 = "bbbbbbbbbbbbbbbbb";
aaaaaaaaaaa是在运行时刻赋值的;
而bbbbbbbbbbb是在编译时就确定的;
但是,在以后的存取中,在栈上的数组比指针所指向的字符串(例如堆)快。
比如:
#include
void main()
{
char a = 1;
char c[] = "1234567890";
char *p ="1234567890";
a = c[1];
a = p[1];
return;
}
对应的汇编代码
10: a = c[1];
00401067 8A 4D F1 mov cl,byte ptr [ebp-0Fh]
0040106A 88 4D FC mov byte ptr [ebp-4],cl
11: a = p[1];
0040106D 8B 55 EC mov edx,dword ptr [ebp-14h]
00401070 8A 42 01 mov al,byte ptr [edx+1]
00401073 88 45 FC mov byte ptr [ebp-4],al
第一种在读取时直接就把字符串中的元素读到寄存器cl中,而第二种则要先把指针值读到edx中,在根据edx读取字符,显然慢了。
2.7小结:
堆和栈的区别可以用如下的比喻来看出:
使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗
菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。
使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。
堆和栈的区别主要分:
操作系统方面的堆和栈,如上面说的那些,不多说了。
还有就是数据结构方面的堆和栈,这些都是不同的概念。这里的堆实际上指的就是(满足堆性质的)优先队列的一种数据结构,第1个元素有最高的优先权;栈实际上就是满足先进后出的性质的数学或数据结构。
虽然堆栈,堆栈的说法是连起来叫,但是他们还是有很大区别的,连着叫只是由于历史的原因。
----http://blog.csdn.net/yulaotou/archive/2009/09/21/4577879.aspx
Tuesday, October 12, 2010
编译原理学习导论
转自 四川大学唐良
CSDN
大学课程为什么要开设编译原理呢?这门课程关注的是编译器方面的产生原理和技术问题,似乎和计算机的基础领域不沾边,可是编译原理却一直作为大学本科的必修课程,同时也成为了研究生入学考试的必考内容。编译原理及技术从本质上来讲就是一个算法问题而已,当然由于这个问题十分复杂,其解决算法也相对复杂。我们学的数据结构与算法分析也是讲算法的,不过讲的基础算法,换句话说讲的是算法导论,而编译原理这门课程讲的就是比较专注解决一种的算法了。在20世纪50年代,编译器的编写一直被认为是十分困难的事情,第一Fortran的编译器据说花了18年的时间才完成。在人们尝试编写编译器的同时,诞生了许多跟编译相关的理论和技术,而这些理论和技术比一个实际的编译器本身价值更大。就犹如数学家们在解决著名的哥德巴赫猜想一样,虽然没有最终解决问题,但是其间诞生不少名著的相关数论。
推荐参考书
虽然编译理论发展到今天,已经有了比较成熟的部分,但是作为一个大学生来说,要自己写出一个像Turboc C,Java那样的编译器来说还是太难了。不仅写编译器困难,学习编译原理这门课程也比较困难。
正是因为编译原理学习相对困难,那么就要求有好的教师和好的教材。教师方面不是我们能自己更改的,而在教材方面我们却可以按自己的意愿来阅读。我下面推荐几本好的编译原理的教材。我推荐的书籍都是国外的经典教材,因为在国内的教材中,确实还没发现什么让人满意的。
第一本书的原名叫《Compilers Principles,Techniques,and Tools》,另外一个响亮的名字就是龙书。原因是这本书的封面上有条红色的龙,也因为这本书在编译原理基础领域确实太有名气了,所以很多国外的学者都直接取名为龙书。最近机械工业出版社已经出版了此书的中文版,名字就叫《编译原理》。该书出的比较早,大概是在85或86年编写完成的,作者之一还是著名的贝尔实验室的科学家。里面讲解的核心编译原理至今都没有变过,所以一直到今天,它的价值都非凡。这本书最大的特点就是一开始就通过一个实际的小例子,把编译原理的大致内容罗列出来,让很多编译原理的初学者很快心里有了个底,也知道为什么会有这些理论,怎么运用这些理论。而这一点是我感觉国内的教材缺乏的东西,所以国内的教材都不是写给愿意自学的读者,总之让人看了半天,却不知道里面的东西有什么用。
第二本书的原名叫《Modern Compiler Design》,中文名字叫做《现代编译程序设计》。该书由人民邮电出版社所出。此书比较关注的是编译原理的实践,书中给出了不少的实际程序代码,还有很多实际的编译技术问题等等。此书另外一个特点就是其“现代”而字。在传统的编译原理教材中,你是不可能看到如同Java中的“垃圾回收”等算法的。因为Java这样的解释执行语言是在近几年才流行起来的东西。如果你想深入学习编译原理的理论知识,那么你肯定得看前面那本龙书,如果你想自己动手做一个先进的编译器,那么你得看这本《现代编译程序设计》。
第三本书就是很多国内的编译原理学者都推荐的那本《编译原理及实践》。或许是这本书引入国内比较早吧,我记得我是在高中就买了这本书,不过也是在前段时间才把整本书看完。此书作为入门教程也的确是个不错的选择。书中给出的编译原理讲解也相当细致,虽然不如前面的龙书那么深入,但是很多地方都是点到为止,作为大学本科教学已经是十分深入了。该书的特点就是注重实践,不过感觉还不如前面那本《现代编译程序设计》的实践味道更重。此书的重点还是在原理上的实践,而非前面那本那样的技术实践。《编译原理及实践》在讲解编译原理的各个部分的同时,也在逐步实践一个现代的编译器Tiny C.等你把整本书看完,差不多自己也可以写一个Tiny C了。作者还对Lex和Yacc这两个常用的编译相关的工具进行了很详细的说明,这一点也是很难在国内的教材中看到的。
推荐了这三本教材,都有英文版和中文版的。很多英文好的同学只喜欢看原版的书,不我的感觉是这三本书的翻译都很不错,没有必要特别去买英文版的。理解理论的实质比理解表面的文字更为重要。
编译原理的实质
前面已经说过,学习编译原理其实也就是学习算法而已,没什么特别的。只不过这些算法的产生已经形成了一套理论。下面我来看看编译原理里面到底有什么高深的理论吧。
几乎每本编译原理的教材都是分成词法分析,语法分析(LL算法,递归下降算法,LR算法),语义分析,运行时环境,中间代码,代码生成,代码优化这些部分。其实现在很多编译原理的教材都是按照85,86出版的那本龙书来安排教学内容的,所以那本龙书的内容格式几乎成了现在编译原理教材的定式,包括国内的教材也是如此。一般来说,大学里面的本科教学是不可能把上面的所有部分都认真讲完的,而是比较偏重于前面几个部分。像代码优化那部分东西,就像个无底洞一样,如果要认真讲,就是单独开一个学期的课也不可能讲得清楚。所以,一般对于本科生,对词法分析和语法分析掌握要求就相对要高一点了。
词法分析相对来说比较简单。可能是词法分析程序本身实现起来很简单吧,很多没有学过编译原理的人也同样可以写出各种各样的词法分析程序。不过编译原理在讲解词法分析的时候,重点把正则表达式和自动机原理加了进来,然后以一种十分标准的方式来讲解词法分析程序的产生。这样的做法道理很明显,就是要让词法分析从程序上升到理论的地步。
语法分析部分就比较麻烦一点了。现在一般有两种语法分析算法,LL自顶向下算法和LR自底向上算法。LL算法还好说,到了LR算法的时候,困难就来了。很多自学编译原理的都是遇到LR算法的理解成问题后就放弃了自学。其实这些东西都是只要大家理解就可以了,又不是像词法分析那样非得自己写出来才算真正的会。像LR算法的语法分析器,一般都是用工具Yacc来生成,实践中完全没有比较自己来实现。对于LL算法中特殊的递归下降算法,因为其实践十分简单,那么就应该要求每个学生都能自己写。当然,现在也有不少好的LL算法的语法分析器,不过要是换在非C平台,比如Java,Delphi,你不能运用YACC工具了,那么你就只有自己来写语法分析器。
等学到词法分析和语法分析时候,你可能会出现这样的疑问:“词法分析和语法分析到底有什么?”就从编译器的角度来讲,编译器需要把程序员写的源程序转换成一种方便处理的数据结构(抽象语法树或语法树),那么这个转换的过程就是通过词法分析和语法分析的。其实词法分析并非一开始就被列入编译器的必备部分,只是我们为了简化语法分析的过程,就把词法分析这种繁琐的工作单独提取出来,就成了现在的词法分析部分。除了编译器部分,在其它地方,词法分析和语法分析也是有用的。比如我们在DOS,Unix,Linux下输入命令的时候,程序如何分析你输入的命令形式,这也是简单的应用。总之,这两部分的工作就是把不“规则”的文本信息转换成一种比较好分析好处理的数据结构。那么为什么编译原理的教程都最终把要分析的源分析转换成“树”这种数据结构呢?数据结构中有Stack, Line,List…这么多数据结构,各自都有各自的特点。但是Tree这种结构有很强的递归性,也就是说我们可以把Tree的任何结点Node提取出来后,它依旧是一颗完整的Tree。这一点符合我们现在编译原理分析的形式语言,比如我们在函数里面使用函树,循环中使用循环,条件中使用条件等等,那么就可以很直观地表示在Tree这种数据结构上。同样,我们在执行形式语言的程序的时候也是如此的递归性。在编译原理后面的代码生成的部分,就会介绍一种堆栈式的中间代码,我们可以根据分析出来的抽象语法树,很容易,很机械地运用递归遍历抽象语法树就可以生成这种指令代码。而这种代码其实也被广泛运用在其它的解释型语言中。像现在流行的Java,.NET,其底层的字节码bytecode,可以说就是这中基于堆栈的指令代码的。
关于语义分析,语法制导翻译,类型检查等等部分,其实都是一种完善前面得到的抽象语法树的过程。比如说,我们写C语言程序的时候,都知道,如果把一个浮点数直接赋值给一个整数,就会出现类型不匹配,那么C语言的编译器是怎么知道的呢?就是通过这一步的类型检查。像C++语言这中支持多态函数的语言,这部分要处理的问题就更多更复杂了。大部编译原理的教材在这部分都是讲解一些比较好的处理策略而已。因为新的问题总是在发生,旧的办法不见得足够解决。
本来说,作为一个编译器,起作用的部分就是用户输入的源程序到最终的代码生成。但是在讲解最终代码生成的时候,又不得不讲解机器运行环境等内容。因为如果你不知道机器是怎么执行最终代码的,那么你当然无法知道如何生成合适的最终代码。这部分内容我自我感觉其意义甚至超过了编译原理本身。因为它会把一个计算机的程序的运行过程都通通排在你面前,你将来可能不会从事编译器的开发工作,但是只要是和计算机软件开发相关的领域,都会涉及到程序的执行过程。运行时环境的讲解会让你更清楚一个计算机程序是怎么存储,怎么装载,怎么执行的。关于部分的内容,我强烈建议大家看看龙书上的讲解,作者从最基本的存储组织,存储分配策略,非局部名字的访问,参数传递,符号表到动态存储分配(malloc,new)都作了十分详细的说明。这些东西都是我们编写平常程序的时候经常要做的事情,但是我们却少去探求其内部是如何完成。
关于中间代码生成,代码生成,代码优化部分的内容就实在不好说了。国内很多教材到了这部分都会很简单地走马观花讲过去,学生听了也只是作为了解,不知道如何运用。不过这部分内容的东西如果要认真讲,单独开一学期的课程都讲不完。在《编译原理及实践》的书上,对于这部分的讲解就恰到好处。作者主要讲解的还是一种以堆栈为基础的指令代码,十分通俗易懂,让人看了后,很容易模仿,自己下来后就可以写自己的代码生成。当然,对于其它代码生成技术,代码优化技术的讲解就十分简单了。如果要仔细研究代码生成技术,其实另外还有本叫做《Advance Compiler Desgin and Implement》,那本书现在由机械工业出版社引进的,十分厚重,而且是英文原版。不过这本书我没有把它列为推荐书给大家,毕竟能把龙书的内容搞清楚,在中国已经就算很不错的高手了,到那个时候再看这本《Advance Compiler Desgin and Implement》也不迟。代码优化部分在大学本科教学中还是一个不太重要的部分,就是算是实践过程中,相信大家也不太运用得到。毕竟,自己做的编译器能正确生成执行代码已经很不错了,还谈什么优化呢?
关于实践
编译原理的课程毕竟还只是讲解原理的课程,不是专门的编译技术课程。这两门课程是有很大的区别的。编译技术更关注实际的编写编译器过程中运用到的技术,而原理的课关注讲解其基本理论。但是计算机科学本身就是一门实践性很强的课程,如果能够学以致用,那才叫真正的学会。李阳在讲解疯狂英语的时候就说到,只要当你会实际中运用一个单词一个词组的时候你才能叫学会了这个单词或者词组,而不是只是知道了它的拼写和意思。其实任何学习都是一样的,如果缺少了实践的结合,你不能算学会。
编译原理的课程主要就是讲解编译器产生的理论和原理,那么很简单,自己写个编译器就是最好的实践过程了。不过你得小心,编译系统可能是所有软件系统中最复杂的系统之一,不然为什么大学里面还会把编译器的编写开成一门叫做编译原理的课程来讲?我很佩服那些学了操作系统原理就开始自己写操作系统,学了编译原理就开始自己写编译器的人们,确实,在中国,敢这么做的学生太少了。且不管你这样做能不能做成功,至少有了这个尝试,会让你的程序设计,系统规划安排的功底增进不少。我下面给出一些关于实践过程中可能会遇到的困难,希望能够在你陷入困境的前帮你一把。
1. Lex和Yacc. 这两工具是作为词法分析很语法分析的工具。如果你自己写一个编译器,我十分不建议你连词法分析这种事情都亲手来写。Lex和Yacc应该是作为每本编译原理的教材的必备内容,可是在国内的教材中缺很少看到。这两个工具是Unix系统下的小东西,如果你要在Windows中运用,那么你最好去下在cygwin这个软件。它是个在Windows下模拟Unix的东东,里面就包含了flex.exe和bison.exe(yacc)这两个工具.这两个工具使用起来还挺麻烦的(其实unix 下的很多十分有用的工具都是这样), 不过在《编译原理与实践》这本书上对于这两个工具的讲解十分详细,还列举了不少实际的例子。
2. 做解释型语言比做生成机器代码的编译器简单。虽然说,做解释型的编译器,像Java那样的,你还得自己去写解释器,不过这样你就不必去查找机器代码的资料了。如果你做生成的最终机器代码编译器可能会遇到问题还有就是寄存器为基础的代码生成方法。前面说过,如果你生成的是以堆栈为基础的代码,那么其代码生成过程十分简单,需要考虑的东西也不多,如果你考虑最终的机器代码生成的话,你必须考虑机器的寄存器如何分配等麻烦的问题。
3. 考虑用别人已经生成的语法文件,尽量不要自己动手写词法文件和语法文件.以前一个朋友曾经说过,写出一个好的程序语言的语法定义,就几乎完成了一个编译器的一半.确实是这样,语法文件的编写是个很难的事情.现在网上到处都可以找到比如C语言,C++,Java, Tiny C,Minus C等语言的词法文件和语法文件,你完全可以自己下下来来用.
在《编译原理及实践》的书中,作者给出了一个Tiny C的全部代码.我自我感觉作者的这个编译器做得很不错,相对于其它php,perl等语言的源代码来说,简单得多,容易看懂,而且很清晰地展现了一个完成的编译系统的实现过程.其源代码可以在作者的网站上下载.
后话
编译原理的学习可能算是一个困难的历程,特别是对于那些不对编译系统感兴趣的同学来说.既然它已经作为了大学本科的必修课程,那么就说明的它引申出来的一套理论在整个计算机科学领域还是占有相对重要的地位.
如果我们考究一下历史,就会发现很多被称为程序设计大师的人都是编译领域的高手.写出第一个微型机上运行的Basic语言的比尔盖茨,设计出Delphi的Borland的”世界上最厉害的程序员”, Sun的JAVA之父, 贝尔实验室的C++之父…
附一篇:
编译原理一般认为是较难的一门课.从网上的评论来看,有人说学了一年半软件理论,就一门编译看不懂;有人甚至说它是大本软件课程里最难的一门;有人抱怨国内的编译教材没有一本容易懂的。 从笔者学习实践来看,第一次学了一个多月,理论部分一知半解,第二次学了一星期,基本看懂词法分析的理论部分,语法分析就一知半解了,第三次学了一星期,才基本看懂词法分析和语法分析.由此看来,这门课确实有难度.网上有的帖子,把编译器的编写搞得高深莫测一般,似乎难度极大,非常人能及. 编译原理究竟难在哪里?笔者的体会,主要在这几点: 1.错误认识: 很多人以为编译原理只能应用在写程序语言的编译器上,觉得用处不大,学习兴趣不高.而且可能觉得写编译器就必须完全手工来写. 2.自动机理论: 象NFA,DFA之类,比较抽象,要费些脑子,特别如果学离散数学时没有学自动机理论的话,更是需要多花点时间. 3.集合论的推演: 主要是一些闭包运算之类,数学基础不好的话,学起来也会感到吃力. 4.LR文法: 主要是又引入了自动机 不管哪本编译教材,即使是绝对经典”龙书”也不例外,都要涉及到这几个难点.由于这些内容本身不好懂,作者有再大的本事,也很难把书写得象小说那么流畅好懂. 明确了难点,接着想对策.大致有这么几种: 1.端正认识: 编译原理在静态文本处理上有广泛的应用,举个简单的例子,把HTML文件转化为纯文本,利用编译原理来实现”非常”简单.理解了编译原理的实用性,大概可以提高学习兴趣. 2.反复看书: 这个办法看起来最笨,却是基本的方法.忘了是哪位名人说过,书只要多看,总能看得懂的. 3.结合源码来看: 这是经典教材Compiler Design in C的作者Allen Hollub建议的方法.这本教材的特色就是包含了大段yacc,lex的代码.这也是个好方法,而且,只有看懂了代码,才能说在根本上理解了理论.当然,要完全看懂yacc的代码,工作量是很大的,而且同样要先理解理论. 4.删繁就简,避重就轻.网上流传较广的一篇《编译原理学习导论》(作者四川大学唐良)就基本是这种思路,对于词法分析,作者避免了自动机理论和集合论推演的介绍,直接搬出源码来,大大降低了理解难度,对于语法分析,作者介绍了递归下降和LL文法及相应的源码,而对LR文法,只说”理解理论就可以了”.虽然这种方法回避了对于难点的学习,但是用这种方法学习,可以在较短时间内编写出一个能够运行的词法分析器和语法分析器,可以大大提高学习积极性. --http://www.pconline.com.cn/pcedu/empolder/life/0504/597581.html
笔者的思路大体上类似第4种方法,但也稍有不同.由于一个偶然的原因, 笔者需要编写一个词法分析器和语法分析器,用于程序源代码的静态分析.开始无从下手,硬着头皮看了点编译原理,觉得困难很大.后来偶然找到一个类似的开源程序,是利用一个叫做PCCTS的编译器自动生成工具开发的,大受启发.开源就是好!笔者找来了一个叫做ANTLR的工具(它是PCCTS的新版,支持生成java,c++和c#代码),又下载了一个c语言的语法文件(因为笔者需要处理c代码文件),然后自己编了少量动作(action)语句,界面代码,分析处理代码等,就这样,在对编译原理所知甚少(以前学过的因为理解不深都忘了,只记得正则表达式)的情况下,仅用一个星期就写出了程序. 这次实践使笔者对编译原理兴趣大增,重新又学了一遍编译原理,并归纳出笔者认为比较实用有效的编译原理学习步骤: 1.先利用ANTLR之类的编译器生成工具,做一个小程序(如上面提到的HTML文件转化成纯文本文件的程序),所需知识只是正则表达式的基本知识和生成工具本身的使用方法(可以看联机帮助和网上教程(tutorial)来掌握). 这样做的好处是: 1)可以体会到编译原理的实用性,提高学习兴趣 2)入门容易,消除编译原理学习的畏难情绪. 3)获得词法分析器和语法分析器的感性认识,有利于加深对理论的理解. 4)获得编译器自动生成工具(compiler compiler)的使用经验,提高解决实际问题的能力.(实际工作很多都不是手编而是利用工具的) 2.象ANTLR之类的工具是开源(open source)的,可研究其源码,以便必要时自己手编分析程序. 3.回过头来看编译原理教材. 这时大概会发现,很多理论很容易懂,剩下的只有上面说的几个难点,多看几遍,重点突破. 4.结合教材所附源码,进一步加深对教材的理解 这里顺便提一下,有的编译原理的教材,对于输入子系统不单立一章来讲,有的甚至完全忽略,笔者认为, 输入子系统相对于词法分析器和语法分析器来说当然简单地多,但也是两者的基础,故有必要看源码来理解.在这方面,ANTLR的实现机制和Lex是不同的(当然和java与c的差异有关),可对照着看. 笔者学习VC++时,深切体会到好教材的重要.笔者开始吃了劣质光盘版”教材”和”21天学VC++”的祸害,看了一个月还如入云雾之中,后来看了《VC++技术内幕》,方才豁然开朗.但是编译原理的教材却似乎质量相差不是特别大,关键还在于合适的方法.以上方法笔者也是误打误撞总结出来的,希望有所参考价值. --http://pcedu.pconline.com.cn/empolder/life/0504/597581_1.html
CSDN
大学课程为什么要开设编译原理呢?这门课程关注的是编译器方面的产生原理和技术问题,似乎和计算机的基础领域不沾边,可是编译原理却一直作为大学本科的必修课程,同时也成为了研究生入学考试的必考内容。编译原理及技术从本质上来讲就是一个算法问题而已,当然由于这个问题十分复杂,其解决算法也相对复杂。我们学的数据结构与算法分析也是讲算法的,不过讲的基础算法,换句话说讲的是算法导论,而编译原理这门课程讲的就是比较专注解决一种的算法了。在20世纪50年代,编译器的编写一直被认为是十分困难的事情,第一Fortran的编译器据说花了18年的时间才完成。在人们尝试编写编译器的同时,诞生了许多跟编译相关的理论和技术,而这些理论和技术比一个实际的编译器本身价值更大。就犹如数学家们在解决著名的哥德巴赫猜想一样,虽然没有最终解决问题,但是其间诞生不少名著的相关数论。
推荐参考书
虽然编译理论发展到今天,已经有了比较成熟的部分,但是作为一个大学生来说,要自己写出一个像Turboc C,Java那样的编译器来说还是太难了。不仅写编译器困难,学习编译原理这门课程也比较困难。
正是因为编译原理学习相对困难,那么就要求有好的教师和好的教材。教师方面不是我们能自己更改的,而在教材方面我们却可以按自己的意愿来阅读。我下面推荐几本好的编译原理的教材。我推荐的书籍都是国外的经典教材,因为在国内的教材中,确实还没发现什么让人满意的。
第一本书的原名叫《Compilers Principles,Techniques,and Tools》,另外一个响亮的名字就是龙书。原因是这本书的封面上有条红色的龙,也因为这本书在编译原理基础领域确实太有名气了,所以很多国外的学者都直接取名为龙书。最近机械工业出版社已经出版了此书的中文版,名字就叫《编译原理》。该书出的比较早,大概是在85或86年编写完成的,作者之一还是著名的贝尔实验室的科学家。里面讲解的核心编译原理至今都没有变过,所以一直到今天,它的价值都非凡。这本书最大的特点就是一开始就通过一个实际的小例子,把编译原理的大致内容罗列出来,让很多编译原理的初学者很快心里有了个底,也知道为什么会有这些理论,怎么运用这些理论。而这一点是我感觉国内的教材缺乏的东西,所以国内的教材都不是写给愿意自学的读者,总之让人看了半天,却不知道里面的东西有什么用。
第二本书的原名叫《Modern Compiler Design》,中文名字叫做《现代编译程序设计》。该书由人民邮电出版社所出。此书比较关注的是编译原理的实践,书中给出了不少的实际程序代码,还有很多实际的编译技术问题等等。此书另外一个特点就是其“现代”而字。在传统的编译原理教材中,你是不可能看到如同Java中的“垃圾回收”等算法的。因为Java这样的解释执行语言是在近几年才流行起来的东西。如果你想深入学习编译原理的理论知识,那么你肯定得看前面那本龙书,如果你想自己动手做一个先进的编译器,那么你得看这本《现代编译程序设计》。
第三本书就是很多国内的编译原理学者都推荐的那本《编译原理及实践》。或许是这本书引入国内比较早吧,我记得我是在高中就买了这本书,不过也是在前段时间才把整本书看完。此书作为入门教程也的确是个不错的选择。书中给出的编译原理讲解也相当细致,虽然不如前面的龙书那么深入,但是很多地方都是点到为止,作为大学本科教学已经是十分深入了。该书的特点就是注重实践,不过感觉还不如前面那本《现代编译程序设计》的实践味道更重。此书的重点还是在原理上的实践,而非前面那本那样的技术实践。《编译原理及实践》在讲解编译原理的各个部分的同时,也在逐步实践一个现代的编译器Tiny C.等你把整本书看完,差不多自己也可以写一个Tiny C了。作者还对Lex和Yacc这两个常用的编译相关的工具进行了很详细的说明,这一点也是很难在国内的教材中看到的。
推荐了这三本教材,都有英文版和中文版的。很多英文好的同学只喜欢看原版的书,不我的感觉是这三本书的翻译都很不错,没有必要特别去买英文版的。理解理论的实质比理解表面的文字更为重要。
编译原理的实质
前面已经说过,学习编译原理其实也就是学习算法而已,没什么特别的。只不过这些算法的产生已经形成了一套理论。下面我来看看编译原理里面到底有什么高深的理论吧。
几乎每本编译原理的教材都是分成词法分析,语法分析(LL算法,递归下降算法,LR算法),语义分析,运行时环境,中间代码,代码生成,代码优化这些部分。其实现在很多编译原理的教材都是按照85,86出版的那本龙书来安排教学内容的,所以那本龙书的内容格式几乎成了现在编译原理教材的定式,包括国内的教材也是如此。一般来说,大学里面的本科教学是不可能把上面的所有部分都认真讲完的,而是比较偏重于前面几个部分。像代码优化那部分东西,就像个无底洞一样,如果要认真讲,就是单独开一个学期的课也不可能讲得清楚。所以,一般对于本科生,对词法分析和语法分析掌握要求就相对要高一点了。
词法分析相对来说比较简单。可能是词法分析程序本身实现起来很简单吧,很多没有学过编译原理的人也同样可以写出各种各样的词法分析程序。不过编译原理在讲解词法分析的时候,重点把正则表达式和自动机原理加了进来,然后以一种十分标准的方式来讲解词法分析程序的产生。这样的做法道理很明显,就是要让词法分析从程序上升到理论的地步。
语法分析部分就比较麻烦一点了。现在一般有两种语法分析算法,LL自顶向下算法和LR自底向上算法。LL算法还好说,到了LR算法的时候,困难就来了。很多自学编译原理的都是遇到LR算法的理解成问题后就放弃了自学。其实这些东西都是只要大家理解就可以了,又不是像词法分析那样非得自己写出来才算真正的会。像LR算法的语法分析器,一般都是用工具Yacc来生成,实践中完全没有比较自己来实现。对于LL算法中特殊的递归下降算法,因为其实践十分简单,那么就应该要求每个学生都能自己写。当然,现在也有不少好的LL算法的语法分析器,不过要是换在非C平台,比如Java,Delphi,你不能运用YACC工具了,那么你就只有自己来写语法分析器。
等学到词法分析和语法分析时候,你可能会出现这样的疑问:“词法分析和语法分析到底有什么?”就从编译器的角度来讲,编译器需要把程序员写的源程序转换成一种方便处理的数据结构(抽象语法树或语法树),那么这个转换的过程就是通过词法分析和语法分析的。其实词法分析并非一开始就被列入编译器的必备部分,只是我们为了简化语法分析的过程,就把词法分析这种繁琐的工作单独提取出来,就成了现在的词法分析部分。除了编译器部分,在其它地方,词法分析和语法分析也是有用的。比如我们在DOS,Unix,Linux下输入命令的时候,程序如何分析你输入的命令形式,这也是简单的应用。总之,这两部分的工作就是把不“规则”的文本信息转换成一种比较好分析好处理的数据结构。那么为什么编译原理的教程都最终把要分析的源分析转换成“树”这种数据结构呢?数据结构中有Stack, Line,List…这么多数据结构,各自都有各自的特点。但是Tree这种结构有很强的递归性,也就是说我们可以把Tree的任何结点Node提取出来后,它依旧是一颗完整的Tree。这一点符合我们现在编译原理分析的形式语言,比如我们在函数里面使用函树,循环中使用循环,条件中使用条件等等,那么就可以很直观地表示在Tree这种数据结构上。同样,我们在执行形式语言的程序的时候也是如此的递归性。在编译原理后面的代码生成的部分,就会介绍一种堆栈式的中间代码,我们可以根据分析出来的抽象语法树,很容易,很机械地运用递归遍历抽象语法树就可以生成这种指令代码。而这种代码其实也被广泛运用在其它的解释型语言中。像现在流行的Java,.NET,其底层的字节码bytecode,可以说就是这中基于堆栈的指令代码的。
关于语义分析,语法制导翻译,类型检查等等部分,其实都是一种完善前面得到的抽象语法树的过程。比如说,我们写C语言程序的时候,都知道,如果把一个浮点数直接赋值给一个整数,就会出现类型不匹配,那么C语言的编译器是怎么知道的呢?就是通过这一步的类型检查。像C++语言这中支持多态函数的语言,这部分要处理的问题就更多更复杂了。大部编译原理的教材在这部分都是讲解一些比较好的处理策略而已。因为新的问题总是在发生,旧的办法不见得足够解决。
本来说,作为一个编译器,起作用的部分就是用户输入的源程序到最终的代码生成。但是在讲解最终代码生成的时候,又不得不讲解机器运行环境等内容。因为如果你不知道机器是怎么执行最终代码的,那么你当然无法知道如何生成合适的最终代码。这部分内容我自我感觉其意义甚至超过了编译原理本身。因为它会把一个计算机的程序的运行过程都通通排在你面前,你将来可能不会从事编译器的开发工作,但是只要是和计算机软件开发相关的领域,都会涉及到程序的执行过程。运行时环境的讲解会让你更清楚一个计算机程序是怎么存储,怎么装载,怎么执行的。关于部分的内容,我强烈建议大家看看龙书上的讲解,作者从最基本的存储组织,存储分配策略,非局部名字的访问,参数传递,符号表到动态存储分配(malloc,new)都作了十分详细的说明。这些东西都是我们编写平常程序的时候经常要做的事情,但是我们却少去探求其内部是如何完成。
关于中间代码生成,代码生成,代码优化部分的内容就实在不好说了。国内很多教材到了这部分都会很简单地走马观花讲过去,学生听了也只是作为了解,不知道如何运用。不过这部分内容的东西如果要认真讲,单独开一学期的课程都讲不完。在《编译原理及实践》的书上,对于这部分的讲解就恰到好处。作者主要讲解的还是一种以堆栈为基础的指令代码,十分通俗易懂,让人看了后,很容易模仿,自己下来后就可以写自己的代码生成。当然,对于其它代码生成技术,代码优化技术的讲解就十分简单了。如果要仔细研究代码生成技术,其实另外还有本叫做《Advance Compiler Desgin and Implement》,那本书现在由机械工业出版社引进的,十分厚重,而且是英文原版。不过这本书我没有把它列为推荐书给大家,毕竟能把龙书的内容搞清楚,在中国已经就算很不错的高手了,到那个时候再看这本《Advance Compiler Desgin and Implement》也不迟。代码优化部分在大学本科教学中还是一个不太重要的部分,就是算是实践过程中,相信大家也不太运用得到。毕竟,自己做的编译器能正确生成执行代码已经很不错了,还谈什么优化呢?
关于实践
编译原理的课程毕竟还只是讲解原理的课程,不是专门的编译技术课程。这两门课程是有很大的区别的。编译技术更关注实际的编写编译器过程中运用到的技术,而原理的课关注讲解其基本理论。但是计算机科学本身就是一门实践性很强的课程,如果能够学以致用,那才叫真正的学会。李阳在讲解疯狂英语的时候就说到,只要当你会实际中运用一个单词一个词组的时候你才能叫学会了这个单词或者词组,而不是只是知道了它的拼写和意思。其实任何学习都是一样的,如果缺少了实践的结合,你不能算学会。
编译原理的课程主要就是讲解编译器产生的理论和原理,那么很简单,自己写个编译器就是最好的实践过程了。不过你得小心,编译系统可能是所有软件系统中最复杂的系统之一,不然为什么大学里面还会把编译器的编写开成一门叫做编译原理的课程来讲?我很佩服那些学了操作系统原理就开始自己写操作系统,学了编译原理就开始自己写编译器的人们,确实,在中国,敢这么做的学生太少了。且不管你这样做能不能做成功,至少有了这个尝试,会让你的程序设计,系统规划安排的功底增进不少。我下面给出一些关于实践过程中可能会遇到的困难,希望能够在你陷入困境的前帮你一把。
1. Lex和Yacc. 这两工具是作为词法分析很语法分析的工具。如果你自己写一个编译器,我十分不建议你连词法分析这种事情都亲手来写。Lex和Yacc应该是作为每本编译原理的教材的必备内容,可是在国内的教材中缺很少看到。这两个工具是Unix系统下的小东西,如果你要在Windows中运用,那么你最好去下在cygwin这个软件。它是个在Windows下模拟Unix的东东,里面就包含了flex.exe和bison.exe(yacc)这两个工具.这两个工具使用起来还挺麻烦的(其实unix 下的很多十分有用的工具都是这样), 不过在《编译原理与实践》这本书上对于这两个工具的讲解十分详细,还列举了不少实际的例子。
2. 做解释型语言比做生成机器代码的编译器简单。虽然说,做解释型的编译器,像Java那样的,你还得自己去写解释器,不过这样你就不必去查找机器代码的资料了。如果你做生成的最终机器代码编译器可能会遇到问题还有就是寄存器为基础的代码生成方法。前面说过,如果你生成的是以堆栈为基础的代码,那么其代码生成过程十分简单,需要考虑的东西也不多,如果你考虑最终的机器代码生成的话,你必须考虑机器的寄存器如何分配等麻烦的问题。
3. 考虑用别人已经生成的语法文件,尽量不要自己动手写词法文件和语法文件.以前一个朋友曾经说过,写出一个好的程序语言的语法定义,就几乎完成了一个编译器的一半.确实是这样,语法文件的编写是个很难的事情.现在网上到处都可以找到比如C语言,C++,Java, Tiny C,Minus C等语言的词法文件和语法文件,你完全可以自己下下来来用.
在《编译原理及实践》的书中,作者给出了一个Tiny C的全部代码.我自我感觉作者的这个编译器做得很不错,相对于其它php,perl等语言的源代码来说,简单得多,容易看懂,而且很清晰地展现了一个完成的编译系统的实现过程.其源代码可以在作者的网站上下载.
后话
编译原理的学习可能算是一个困难的历程,特别是对于那些不对编译系统感兴趣的同学来说.既然它已经作为了大学本科的必修课程,那么就说明的它引申出来的一套理论在整个计算机科学领域还是占有相对重要的地位.
如果我们考究一下历史,就会发现很多被称为程序设计大师的人都是编译领域的高手.写出第一个微型机上运行的Basic语言的比尔盖茨,设计出Delphi的Borland的”世界上最厉害的程序员”, Sun的JAVA之父, 贝尔实验室的C++之父…
附一篇:
编译原理一般认为是较难的一门课.从网上的评论来看,有人说学了一年半软件理论,就一门编译看不懂;有人甚至说它是大本软件课程里最难的一门;有人抱怨国内的编译教材没有一本容易懂的。 从笔者学习实践来看,第一次学了一个多月,理论部分一知半解,第二次学了一星期,基本看懂词法分析的理论部分,语法分析就一知半解了,第三次学了一星期,才基本看懂词法分析和语法分析.由此看来,这门课确实有难度.网上有的帖子,把编译器的编写搞得高深莫测一般,似乎难度极大,非常人能及. 编译原理究竟难在哪里?笔者的体会,主要在这几点: 1.错误认识: 很多人以为编译原理只能应用在写程序语言的编译器上,觉得用处不大,学习兴趣不高.而且可能觉得写编译器就必须完全手工来写. 2.自动机理论: 象NFA,DFA之类,比较抽象,要费些脑子,特别如果学离散数学时没有学自动机理论的话,更是需要多花点时间. 3.集合论的推演: 主要是一些闭包运算之类,数学基础不好的话,学起来也会感到吃力. 4.LR文法: 主要是又引入了自动机 不管哪本编译教材,即使是绝对经典”龙书”也不例外,都要涉及到这几个难点.由于这些内容本身不好懂,作者有再大的本事,也很难把书写得象小说那么流畅好懂. 明确了难点,接着想对策.大致有这么几种: 1.端正认识: 编译原理在静态文本处理上有广泛的应用,举个简单的例子,把HTML文件转化为纯文本,利用编译原理来实现”非常”简单.理解了编译原理的实用性,大概可以提高学习兴趣. 2.反复看书: 这个办法看起来最笨,却是基本的方法.忘了是哪位名人说过,书只要多看,总能看得懂的. 3.结合源码来看: 这是经典教材Compiler Design in C的作者Allen Hollub建议的方法.这本教材的特色就是包含了大段yacc,lex的代码.这也是个好方法,而且,只有看懂了代码,才能说在根本上理解了理论.当然,要完全看懂yacc的代码,工作量是很大的,而且同样要先理解理论. 4.删繁就简,避重就轻.网上流传较广的一篇《编译原理学习导论》(作者四川大学唐良)就基本是这种思路,对于词法分析,作者避免了自动机理论和集合论推演的介绍,直接搬出源码来,大大降低了理解难度,对于语法分析,作者介绍了递归下降和LL文法及相应的源码,而对LR文法,只说”理解理论就可以了”.虽然这种方法回避了对于难点的学习,但是用这种方法学习,可以在较短时间内编写出一个能够运行的词法分析器和语法分析器,可以大大提高学习积极性. --http://www.pconline.com.cn/pcedu/empolder/life/0504/597581.html
笔者的思路大体上类似第4种方法,但也稍有不同.由于一个偶然的原因, 笔者需要编写一个词法分析器和语法分析器,用于程序源代码的静态分析.开始无从下手,硬着头皮看了点编译原理,觉得困难很大.后来偶然找到一个类似的开源程序,是利用一个叫做PCCTS的编译器自动生成工具开发的,大受启发.开源就是好!笔者找来了一个叫做ANTLR的工具(它是PCCTS的新版,支持生成java,c++和c#代码),又下载了一个c语言的语法文件(因为笔者需要处理c代码文件),然后自己编了少量动作(action)语句,界面代码,分析处理代码等,就这样,在对编译原理所知甚少(以前学过的因为理解不深都忘了,只记得正则表达式)的情况下,仅用一个星期就写出了程序. 这次实践使笔者对编译原理兴趣大增,重新又学了一遍编译原理,并归纳出笔者认为比较实用有效的编译原理学习步骤: 1.先利用ANTLR之类的编译器生成工具,做一个小程序(如上面提到的HTML文件转化成纯文本文件的程序),所需知识只是正则表达式的基本知识和生成工具本身的使用方法(可以看联机帮助和网上教程(tutorial)来掌握). 这样做的好处是: 1)可以体会到编译原理的实用性,提高学习兴趣 2)入门容易,消除编译原理学习的畏难情绪. 3)获得词法分析器和语法分析器的感性认识,有利于加深对理论的理解. 4)获得编译器自动生成工具(compiler compiler)的使用经验,提高解决实际问题的能力.(实际工作很多都不是手编而是利用工具的) 2.象ANTLR之类的工具是开源(open source)的,可研究其源码,以便必要时自己手编分析程序. 3.回过头来看编译原理教材. 这时大概会发现,很多理论很容易懂,剩下的只有上面说的几个难点,多看几遍,重点突破. 4.结合教材所附源码,进一步加深对教材的理解 这里顺便提一下,有的编译原理的教材,对于输入子系统不单立一章来讲,有的甚至完全忽略,笔者认为, 输入子系统相对于词法分析器和语法分析器来说当然简单地多,但也是两者的基础,故有必要看源码来理解.在这方面,ANTLR的实现机制和Lex是不同的(当然和java与c的差异有关),可对照着看. 笔者学习VC++时,深切体会到好教材的重要.笔者开始吃了劣质光盘版”教材”和”21天学VC++”的祸害,看了一个月还如入云雾之中,后来看了《VC++技术内幕》,方才豁然开朗.但是编译原理的教材却似乎质量相差不是特别大,关键还在于合适的方法.以上方法笔者也是误打误撞总结出来的,希望有所参考价值. --http://pcedu.pconline.com.cn/empolder/life/0504/597581_1.html
Saturday, October 2, 2010
Why is the Federal Reserve Buying US Treasury Bills?
http://econ.economicshelp.org/2008/12/why-is-federal-reserve-buying-us.html
今天和友人讨论到为何Federal要购买债券, 我顺手查了点资料, 转发一篇写得比较简单的.
At the moment banks are reluctant to lend to the private sector. This is because the recession has made lending to private companies quite risky. Also, banks are reluctant to lend to each other because of the credit crunch. Banks are buying 30 year treasury bonds because they are seen as a safe investment. They may only yield 2%, but with interest rates at 0-0.25%, it does represent some profit for a bank; in addition it is seen as safe.
Because the Fed is worried about deflation and lack of credit, they are trying to get the banks to resume more normal lending practices (lending to each other and lending to private sector.
The Federal Reserve are buying treasury bonds because:
* By buying bonds, the value increases and the interest rate on them declines. The Fed are trying to reduce interest rates on long term bonds to encourage banks to spend less money on buying Treasury bonds and lend more to private sector. (If treasury yields fell to 0%, it is less attractive to buy bonds)
* The Federal Reserve are also trying to improve the balance sheet of banks by buying 'toxic assets' - mortgage backed securities which currently have little market value.
If successful, this will create inflationary expectations (rather than deflation), encourage lending and therefore encourage economic growth.
Problems With This Scheme
1. The Federal Reserve are increasing the monetary base, there is a danger this could lead to high levels of inflation, when the velocity of circulation picks up.
2. Increasing quantity of US dollars and reducing interest rates on bonds is likely to reduce value of dollar, so dollar is likely to fall.
3. US National Debt is over 73% of GDP and is increasing all the time. This relies on people being willing to buy bonds and finance the debt.
4. The worry is that lower interest rates and a falling dollar, will discourage foreign investors from holding US treasury bills and bonds. Then the US would struggle to finance its national debt. This would then cause either inflation (potentially very high) or an increase in interest rates to attract savers.
A key issues is whether:
* Investors retain trust in the dollar
* The US government's credit worthiness - If people feared US government could default this would create real problems for the US dollar and US deficit.
今天和友人讨论到为何Federal要购买债券, 我顺手查了点资料, 转发一篇写得比较简单的.
The Federal Reserve are buying 30 year Treasury Bills in an attempt to increase the money supply and stimulate economic activity.
At the moment banks are reluctant to lend to the private sector. This is because the recession has made lending to private companies quite risky. Also, banks are reluctant to lend to each other because of the credit crunch. Banks are buying 30 year treasury bonds because they are seen as a safe investment. They may only yield 2%, but with interest rates at 0-0.25%, it does represent some profit for a bank; in addition it is seen as safe.
Because the Fed is worried about deflation and lack of credit, they are trying to get the banks to resume more normal lending practices (lending to each other and lending to private sector.
The Federal Reserve are buying treasury bonds because:
* By buying bonds, the value increases and the interest rate on them declines. The Fed are trying to reduce interest rates on long term bonds to encourage banks to spend less money on buying Treasury bonds and lend more to private sector. (If treasury yields fell to 0%, it is less attractive to buy bonds)
* The Federal Reserve are also trying to improve the balance sheet of banks by buying 'toxic assets' - mortgage backed securities which currently have little market value.
If successful, this will create inflationary expectations (rather than deflation), encourage lending and therefore encourage economic growth.
Problems With This Scheme
1. The Federal Reserve are increasing the monetary base, there is a danger this could lead to high levels of inflation, when the velocity of circulation picks up.
2. Increasing quantity of US dollars and reducing interest rates on bonds is likely to reduce value of dollar, so dollar is likely to fall.
3. US National Debt is over 73% of GDP and is increasing all the time. This relies on people being willing to buy bonds and finance the debt.
4. The worry is that lower interest rates and a falling dollar, will discourage foreign investors from holding US treasury bills and bonds. Then the US would struggle to finance its national debt. This would then cause either inflation (potentially very high) or an increase in interest rates to attract savers.
A key issues is whether:
* Investors retain trust in the dollar
* The US government's credit worthiness - If people feared US government could default this would create real problems for the US dollar and US deficit.
Friday, September 17, 2010
闲话GEB
按:
研究生课程里学了半年的C++, 自以为各种语法钻得很细, 一些巧妙的算法花一定功夫也能琢磨出来. 但实习的时候真正开始写大的project的时候就傻眼了. 现在看来, 编程的一方面乐趣可以叫做:规则, 这教会我们怎样从基本的语句和各种元素发展成庞大的工程; 另一方面乐趣逆过来思考, 就是如何把庞大的工程, 生活中的问题, 或许是跟编程完全无联系的东西拆解成可以用计算机执行的基本元素, 这是反向的过程, 同时也是更实际的问题. 两头都打通了, 智力就更上一个层次了.
转自豆瓣 GEB书评
http://book.douban.com/review/1596919/
GEB(《哥德尔,埃舍尔和巴赫——集异璧之大成》)是本妙书。作为标题的三个人,两个跟我是老 朋友——巴赫和哥德尔。从计算机科学来看,如果说得玄一点,不确定性原理以及图灵机这样的概念,是可以当成哲学来说的。巴赫老人家的音乐在某种意义上也可 以当作神秘主义符号来说。荷兰画家埃舍尔我了解有限,不过作品倒还很合我口味:充满悖论和幻觉。
总的来说,我们这个世界是可以被不同的定义和推演 所描述的。拟定一个方向,所有的“数”都乖乖地沿它长下去。至于“语言”,说白了就是从游戏规则出发——可能是荒谬的规则,但从这规则你可以定义整个世 界。世界被一条描述分成两半:属于和不属于。巴赫的音乐可以被解释出一种“数字意”,因为他一直在攀爬,重复,不经意间回到起点。我常常把巴赫的灵感,想 成一种荒诞的规则,一颗怪异的种子。在羽管键琴的机械敲打中,种子当当当地长成盘旋的绿藤。
也正因为此,我一直悄悄把写复调的作曲家巴赫当成现代艺术家,拓扑观念的高手。
隐喻
个人一向反对硬做文章式地联系科学和艺术。自己乐意做个老实人,哪怕被人称 为只见树木不见森林的工匠,盯住细节死板地研究。然而我又认为,从艺术和科学层面去想,其实不应看成对艺术和科学的归纳,而是走出新的一径,对世界重新定 义。我常常嘲笑那种要用科学解释艺术的人,是把立体的东西放到二维座标系中按扁,然而按GEB的作者的目光看去,不是把三维按成二维,而是让它长成四维 了。如今我不由自主深深赞美这种新鲜的眼光。顺手拈来一则,是作者谈 “堆栈” 。堆栈是一种程序中常用的数据结构,即存数据是先进先出(比如一节节车厢通过山洞) 还是先进后出(如同一头堵死的竹筒) 。作者用巴赫的晚期杰作《赋格的艺术》来讲它,“紧张和释放是音乐进行的基本动力”,《赋格的艺术》中,先用转调形成一种压力,然后在那个基础上继续变 形,而解开压力的顺序与之相反——倒退着解开。呵呵,把巴赫和堆栈联系在一起的人,应该受我一拜。
我读计算机系硕士的导师,专门搞一些“形式语 言”,让我们活活抓狂而死。那时我们定义语言,总有一项是unknown(未知,未定义)。GEB的作者Hofstadter画了一幅图,两棵树,一黑一 白,中间有unreachable falsehoods & unreachable truths。一个“异常”就一下子把过程扔到深渊里去了,最后扑通扔出一个错误信息了事。在我看来,这其实是对世界的一种隐喻。计算机科学充满了这种对 人世的模仿和寓言。比如图灵机,答答答答地在带子上打出结果,有时有确定的答案,有时没有。这个东西奇妙在完全不能用实验印证。我们做题听课热火朝天,却 完全是在一个乌托邦里闹,根本看不到后果。我们的证明,往往就是为得出一个“不可解”的结论,在一个并不存在的空间里,我们抓瞎着在概念丛中穿行。
当 然,习惯了那些概念丛,它们就是真的了,比真还真,成为意识的一部分。而里面的磕磕碰碰,都有真实质感。素质好的人,从一丝碰撞的触觉摸去,就能撞见个新 洞天。我过去有个很年轻的老师,读硕士时就发表了很出色的论文。后来他不无得意地对我们回忆那个下午,一个闷热孤单的地方,他一个人郁闷一大顿之后,给外 出开会的导师发了一封振聋发聩的邮件,汇报自己的发现。有一次,我问他,你的研究其实根本不用计算机,对吗?他笑着举起一张写了些铅笔字的小纸片,看,这 就是我的全部研究。
递归
上面说了图灵机。它不是真实的机器,是一种抽象数学模型,用纸带模拟数学运 算。看上去,它原始得不可思议,但又永恒得不可思议。因为假设纸带无限长,又假设可以保存整个纸带的当前状况。它正是计算机的理论模型和概念的开端。英国 数学家图灵认为这样的假想“机器”就能模拟人类所能进行的任何计算过程——抵达如此简洁的概括,真乃天才。
同为英国人的散文家兰姆,写过一个半小 说半散文的东西,说某个国家(似乎是中国)的一个男孩发现房子烧毁了,碰巧烤熟猪肉,就很好吃。为了有熟猪肉,他们就一间一间地烧房子。现在看来,早期计 算机的思想,简直就是这样,笨手笨脚地绕许多弯才能解决一个最最简单的问题。其实,现在的机器定理证明也是这样的,对初学者来说,证明x+1 > x 需要繁琐的定义,动辄面对大量错误信息。然而那就是计算机的发端,跟人类直觉思维截然不同的思考方式。从那里开始,人的思想史开始了新的头绪—当人发现自 己的直觉太过聪明,聪明到了头,打算换成笨办法的时候,才开始了一种“可持续发展”的新聪明。
递归本来是一种编程技术,简单地说,是让一个函数从 其内部调用其自身。比如计算阶乘。0 的阶乘被特别地定义为 1。 更大数的阶乘是通过计算 1 * 2 *…来求得的,每次增加 1,直至达到要计算其阶乘的那个数。也就是说,每一步都保存形式(每次增加1),但变更内容(被增加的数字时刻在变化),变到你不需要再变为止。递归思路 本身和编程应用都不太直观,需要学习和适应,才能有对“样式” 的坚强守护——它不是保留一个具体公式反复调用和推算,而是保持一个“样式”,比如一个数乘以一个比它小1的数,这个“比它小1”的“它”,每次都变,所 以设计者必须在脑子里整好这个样式和结构,能够在抽象的状态中,从抽象到抽象。
而递归一旦开始,形式就固定了,只有到了终止条件才停住。条件未满 足的时候,闭眼往前走即可。也就是说,这个过程完全不用知道整体的信息,而是只关心前一步结果是什么,然后据此推出下一步是什么,至于以后是什么,旁边是 什么,前一步的前一步,完全不管,它闭着眼睛摸黑走下去。这种对自身的不停调用的方式,好象混凝土一样,高效地合成整个世界。在我看来,递归是一种认知哲 学:把所知减到最少,驴拉磨一样。最少产生了最多——由最低能的图灵机生出计算机,由最简易的程序生发出人工智能。
美国人Mitchell Waldrop写过一本叫做《复杂》的书,说的是一群博士研究生命科学,提到进化,认为以达尔文的理论,人能从无序的生命,进化成如今的样子,机率不超过 猴子在打字机上乱打,打出莎士比亚全集。有人说,最早的有机分子,由少数粘合成“大分子” ,一步步继续粘合,长成更“大”的生物,经过多少万年的进化、选择、粘合,才有了生命。不论是否经过证实,至少在我听来是有道理的。说到底,这理论仍然是 一种“生命递归”,由种子开始,由少变多,由小变大,动态积累,不能跳步。生命其实是盲目的,不知道自己在整体中的位置,只能从现存状态做有限的挣扎,当 然,不像计算机算法那样处于封闭状态,而是不时受扰动和灾难,可能犯错误、跃进、终止。这流向仍然是一般意义上的递归:发端是一种难以言说的天意或者“第 一推动”,而生命如默默跟着头羊走的羊群,不知所来,不知所终。
出发
递归在我眼中也意味着生命的无限——纸带无限长,记忆无限多,可以运行无限 的时间。而以递归为本的图灵机,却从一开始就既盲目,又“知道”自己的局限——图灵用它证明第一个不可决定问题——图灵机会不会停。结论是,没有一个一般 规律能够决定,对一些输入和算法,图灵机停还是不停。停,这里是个预定条件,比如我可规定,移动的读写头走到某位置,整个机器停下来。条件因机器游戏规则 而异,而最后我们知道的是,我们什么也不知道,无法一般性地预言,那个期待的地方能否抵达。因为一旦预言,结论必然矛盾,所以只好不预言。
所以,生命出发了,然而不知道有没有终点,不知道前进的意义。上帝预设了谜给我们,一代一代才有兴致递归式生存,不知所终。我们是快乐的亚当夏娃。
在 我看来,一方面,“样式” 是一种存在——一种由物质构成的“宏物质”——它粘合物质,把猴子向人带领。所以你我是一堆物理化学生物实体,更是“样式”的迭加计算结果---如果非要 用计算机模拟一下,我们的一举一动,一颦一笑,都是无数递归计算的结果,从此时可倒推到生命之初。而另一方面,“样式”这个东西,又可类比为人世中的“精 神层面”,因为人只有运用智力才能吸收并且保持形式。所谓精神、智慧、道德、伦理之类,可以跟物质保持一定的独立,这正是“形式”跟“内容”的关系。上面 说过,N的阶乘,N乘以N-1, 一直乘下去,不到那个尽头的1,也就是物质资源完全用光,这个形式一直保持,无论N有多小。
跑题一下,记得 历史学家吉多(H.D. Kitto) 的《希腊历史》引言里说,与古希腊同时的民族,比如希伯莱,埃及等等,生活经验和智慧上本来一点不逊于古希腊,而且这些民族,各自有自己的文学传世。然而 只有希腊人形成了真正的科学,为什么?因为只有他们有意识地交流和总结,把数学哲学变成体系的学问,流传下来。相比较而言,希伯莱人积累的生活经验却一代 代化为云烟。古希腊人跟当时别的民族的比较,好比成人的智力跟儿童智力的比较。说到底,文化的积累本来都是递归式,然而还远远不够,因为递归中的元素,自 己不携带任何全局信息。大家盲目地跟着眼前的法则走,不介意整体状态,走到南墙活活撞死也得认命。
递归的伟大在于将它抽象成“样式”的人。被递归的元素,却可舒坦地保持弱智状态。而人的社会,总要有人站在递归之外,为递归洪流设置终止条件吧。
抵达
音乐上有荒岛CD一说,那么“荒岛书”可就太多了。对我来说,GEB算一本,斯宾格勒的《西方的没落》也算一本。到了一个荒岛上,你念念不忘这个世界横竖在没落,左一文明,右一文明,“神龟虽寿,尤有竟时”,既然生出来也要衰落,那为什么还生呢?
而GEB 是一本阳光之书。我每天等咖啡烧好那片刻都在读。今天下午在科学楼底买了只水果冰激淋,吃的时候不知看什么,就看它。那时,自己坐在圆桌跟前,周围的老师 同学也在买咖啡和冰激凌。书真是旧了,书皮从书脊脱落,落下很多黄屑。此刻,圆桌、黄屑,这些沙沙作响的东西,都可成为“观念”。在荒芜的桌旁,我凝视书 中的巴赫音乐谱例。其实,这本书里谈论巴赫的部份并非发前人所未发,毕竟作者不是音乐家。不过作者将数学和计算机的想法跟巴赫联系一下,有时别有奇趣。比 如说到巴赫的Hemiola和声,作者说,这是世界的不确定性。说得太简单干脆,让我以为这是我说的,简直想跳起来跟作者争版权。
巴赫的管风琴赋 格作品的结尾,常有这种和声,节奏飘忽地变了一下,很蛮不讲理地把乐意扯到别处,给听者吃了贴迷幻药。那时我就想,上帝为我们设计巴赫这个人物的存在,是 跟量子力学一道给人类准备好的礼物。人秉承牛顿之意似乎把这个世界越算越妥贴,然而最终上帝撕碎我们的信心,毁掉人的骄傲。这一切,真是一种轮回。
依 我看,GEB缺了重要的内容。如果我写,定要加上美国诗人史蒂文斯(Wallace Stevens)。史蒂文斯的诗歌充满荒诞意象,在我看来,往往是是对世界的拓朴式解构,赤裸裸的循环递归迭代,把信仰都绕进去。他喜欢写“一个基督徒女 人”这种题目,更喜欢慢条斯理地细细数来“十三种方式看黑鸟”,喜欢追究“存在”、“记忆”、“消失”。注意,在我看来,这些理念都“后计算机”得不得 了,而且自己丁丁当当搭起概念集合的架子。而且,他的诗意是放射性的,从语词中心出发,从那些华丽怪诞的动物名或者地名出发,最后形成凸多边形——是凸 的,不包括弯弯的蚕豆那样内凹的形状。
我们就这样站在荒岛上,看各种轮回,看船来船往。
研究生课程里学了半年的C++, 自以为各种语法钻得很细, 一些巧妙的算法花一定功夫也能琢磨出来. 但实习的时候真正开始写大的project的时候就傻眼了. 现在看来, 编程的一方面乐趣可以叫做:规则, 这教会我们怎样从基本的语句和各种元素发展成庞大的工程; 另一方面乐趣逆过来思考, 就是如何把庞大的工程, 生活中的问题, 或许是跟编程完全无联系的东西拆解成可以用计算机执行的基本元素, 这是反向的过程, 同时也是更实际的问题. 两头都打通了, 智力就更上一个层次了.
转自豆瓣 GEB书评
http://book.douban.com/review/1596919/
GEB(《哥德尔,埃舍尔和巴赫——集异璧之大成》)是本妙书。作为标题的三个人,两个跟我是老 朋友——巴赫和哥德尔。从计算机科学来看,如果说得玄一点,不确定性原理以及图灵机这样的概念,是可以当成哲学来说的。巴赫老人家的音乐在某种意义上也可 以当作神秘主义符号来说。荷兰画家埃舍尔我了解有限,不过作品倒还很合我口味:充满悖论和幻觉。
总的来说,我们这个世界是可以被不同的定义和推演 所描述的。拟定一个方向,所有的“数”都乖乖地沿它长下去。至于“语言”,说白了就是从游戏规则出发——可能是荒谬的规则,但从这规则你可以定义整个世 界。世界被一条描述分成两半:属于和不属于。巴赫的音乐可以被解释出一种“数字意”,因为他一直在攀爬,重复,不经意间回到起点。我常常把巴赫的灵感,想 成一种荒诞的规则,一颗怪异的种子。在羽管键琴的机械敲打中,种子当当当地长成盘旋的绿藤。
也正因为此,我一直悄悄把写复调的作曲家巴赫当成现代艺术家,拓扑观念的高手。
隐喻
个人一向反对硬做文章式地联系科学和艺术。自己乐意做个老实人,哪怕被人称 为只见树木不见森林的工匠,盯住细节死板地研究。然而我又认为,从艺术和科学层面去想,其实不应看成对艺术和科学的归纳,而是走出新的一径,对世界重新定 义。我常常嘲笑那种要用科学解释艺术的人,是把立体的东西放到二维座标系中按扁,然而按GEB的作者的目光看去,不是把三维按成二维,而是让它长成四维 了。如今我不由自主深深赞美这种新鲜的眼光。顺手拈来一则,是作者谈 “堆栈” 。堆栈是一种程序中常用的数据结构,即存数据是先进先出(比如一节节车厢通过山洞) 还是先进后出(如同一头堵死的竹筒) 。作者用巴赫的晚期杰作《赋格的艺术》来讲它,“紧张和释放是音乐进行的基本动力”,《赋格的艺术》中,先用转调形成一种压力,然后在那个基础上继续变 形,而解开压力的顺序与之相反——倒退着解开。呵呵,把巴赫和堆栈联系在一起的人,应该受我一拜。
我读计算机系硕士的导师,专门搞一些“形式语 言”,让我们活活抓狂而死。那时我们定义语言,总有一项是unknown(未知,未定义)。GEB的作者Hofstadter画了一幅图,两棵树,一黑一 白,中间有unreachable falsehoods & unreachable truths。一个“异常”就一下子把过程扔到深渊里去了,最后扑通扔出一个错误信息了事。在我看来,这其实是对世界的一种隐喻。计算机科学充满了这种对 人世的模仿和寓言。比如图灵机,答答答答地在带子上打出结果,有时有确定的答案,有时没有。这个东西奇妙在完全不能用实验印证。我们做题听课热火朝天,却 完全是在一个乌托邦里闹,根本看不到后果。我们的证明,往往就是为得出一个“不可解”的结论,在一个并不存在的空间里,我们抓瞎着在概念丛中穿行。
当 然,习惯了那些概念丛,它们就是真的了,比真还真,成为意识的一部分。而里面的磕磕碰碰,都有真实质感。素质好的人,从一丝碰撞的触觉摸去,就能撞见个新 洞天。我过去有个很年轻的老师,读硕士时就发表了很出色的论文。后来他不无得意地对我们回忆那个下午,一个闷热孤单的地方,他一个人郁闷一大顿之后,给外 出开会的导师发了一封振聋发聩的邮件,汇报自己的发现。有一次,我问他,你的研究其实根本不用计算机,对吗?他笑着举起一张写了些铅笔字的小纸片,看,这 就是我的全部研究。
递归
上面说了图灵机。它不是真实的机器,是一种抽象数学模型,用纸带模拟数学运 算。看上去,它原始得不可思议,但又永恒得不可思议。因为假设纸带无限长,又假设可以保存整个纸带的当前状况。它正是计算机的理论模型和概念的开端。英国 数学家图灵认为这样的假想“机器”就能模拟人类所能进行的任何计算过程——抵达如此简洁的概括,真乃天才。
同为英国人的散文家兰姆,写过一个半小 说半散文的东西,说某个国家(似乎是中国)的一个男孩发现房子烧毁了,碰巧烤熟猪肉,就很好吃。为了有熟猪肉,他们就一间一间地烧房子。现在看来,早期计 算机的思想,简直就是这样,笨手笨脚地绕许多弯才能解决一个最最简单的问题。其实,现在的机器定理证明也是这样的,对初学者来说,证明x+1 > x 需要繁琐的定义,动辄面对大量错误信息。然而那就是计算机的发端,跟人类直觉思维截然不同的思考方式。从那里开始,人的思想史开始了新的头绪—当人发现自 己的直觉太过聪明,聪明到了头,打算换成笨办法的时候,才开始了一种“可持续发展”的新聪明。
递归本来是一种编程技术,简单地说,是让一个函数从 其内部调用其自身。比如计算阶乘。0 的阶乘被特别地定义为 1。 更大数的阶乘是通过计算 1 * 2 *…来求得的,每次增加 1,直至达到要计算其阶乘的那个数。也就是说,每一步都保存形式(每次增加1),但变更内容(被增加的数字时刻在变化),变到你不需要再变为止。递归思路 本身和编程应用都不太直观,需要学习和适应,才能有对“样式” 的坚强守护——它不是保留一个具体公式反复调用和推算,而是保持一个“样式”,比如一个数乘以一个比它小1的数,这个“比它小1”的“它”,每次都变,所 以设计者必须在脑子里整好这个样式和结构,能够在抽象的状态中,从抽象到抽象。
而递归一旦开始,形式就固定了,只有到了终止条件才停住。条件未满 足的时候,闭眼往前走即可。也就是说,这个过程完全不用知道整体的信息,而是只关心前一步结果是什么,然后据此推出下一步是什么,至于以后是什么,旁边是 什么,前一步的前一步,完全不管,它闭着眼睛摸黑走下去。这种对自身的不停调用的方式,好象混凝土一样,高效地合成整个世界。在我看来,递归是一种认知哲 学:把所知减到最少,驴拉磨一样。最少产生了最多——由最低能的图灵机生出计算机,由最简易的程序生发出人工智能。
美国人Mitchell Waldrop写过一本叫做《复杂》的书,说的是一群博士研究生命科学,提到进化,认为以达尔文的理论,人能从无序的生命,进化成如今的样子,机率不超过 猴子在打字机上乱打,打出莎士比亚全集。有人说,最早的有机分子,由少数粘合成“大分子” ,一步步继续粘合,长成更“大”的生物,经过多少万年的进化、选择、粘合,才有了生命。不论是否经过证实,至少在我听来是有道理的。说到底,这理论仍然是 一种“生命递归”,由种子开始,由少变多,由小变大,动态积累,不能跳步。生命其实是盲目的,不知道自己在整体中的位置,只能从现存状态做有限的挣扎,当 然,不像计算机算法那样处于封闭状态,而是不时受扰动和灾难,可能犯错误、跃进、终止。这流向仍然是一般意义上的递归:发端是一种难以言说的天意或者“第 一推动”,而生命如默默跟着头羊走的羊群,不知所来,不知所终。
出发
递归在我眼中也意味着生命的无限——纸带无限长,记忆无限多,可以运行无限 的时间。而以递归为本的图灵机,却从一开始就既盲目,又“知道”自己的局限——图灵用它证明第一个不可决定问题——图灵机会不会停。结论是,没有一个一般 规律能够决定,对一些输入和算法,图灵机停还是不停。停,这里是个预定条件,比如我可规定,移动的读写头走到某位置,整个机器停下来。条件因机器游戏规则 而异,而最后我们知道的是,我们什么也不知道,无法一般性地预言,那个期待的地方能否抵达。因为一旦预言,结论必然矛盾,所以只好不预言。
所以,生命出发了,然而不知道有没有终点,不知道前进的意义。上帝预设了谜给我们,一代一代才有兴致递归式生存,不知所终。我们是快乐的亚当夏娃。
在 我看来,一方面,“样式” 是一种存在——一种由物质构成的“宏物质”——它粘合物质,把猴子向人带领。所以你我是一堆物理化学生物实体,更是“样式”的迭加计算结果---如果非要 用计算机模拟一下,我们的一举一动,一颦一笑,都是无数递归计算的结果,从此时可倒推到生命之初。而另一方面,“样式”这个东西,又可类比为人世中的“精 神层面”,因为人只有运用智力才能吸收并且保持形式。所谓精神、智慧、道德、伦理之类,可以跟物质保持一定的独立,这正是“形式”跟“内容”的关系。上面 说过,N的阶乘,N乘以N-1, 一直乘下去,不到那个尽头的1,也就是物质资源完全用光,这个形式一直保持,无论N有多小。
跑题一下,记得 历史学家吉多(H.D. Kitto) 的《希腊历史》引言里说,与古希腊同时的民族,比如希伯莱,埃及等等,生活经验和智慧上本来一点不逊于古希腊,而且这些民族,各自有自己的文学传世。然而 只有希腊人形成了真正的科学,为什么?因为只有他们有意识地交流和总结,把数学哲学变成体系的学问,流传下来。相比较而言,希伯莱人积累的生活经验却一代 代化为云烟。古希腊人跟当时别的民族的比较,好比成人的智力跟儿童智力的比较。说到底,文化的积累本来都是递归式,然而还远远不够,因为递归中的元素,自 己不携带任何全局信息。大家盲目地跟着眼前的法则走,不介意整体状态,走到南墙活活撞死也得认命。
递归的伟大在于将它抽象成“样式”的人。被递归的元素,却可舒坦地保持弱智状态。而人的社会,总要有人站在递归之外,为递归洪流设置终止条件吧。
抵达
音乐上有荒岛CD一说,那么“荒岛书”可就太多了。对我来说,GEB算一本,斯宾格勒的《西方的没落》也算一本。到了一个荒岛上,你念念不忘这个世界横竖在没落,左一文明,右一文明,“神龟虽寿,尤有竟时”,既然生出来也要衰落,那为什么还生呢?
而GEB 是一本阳光之书。我每天等咖啡烧好那片刻都在读。今天下午在科学楼底买了只水果冰激淋,吃的时候不知看什么,就看它。那时,自己坐在圆桌跟前,周围的老师 同学也在买咖啡和冰激凌。书真是旧了,书皮从书脊脱落,落下很多黄屑。此刻,圆桌、黄屑,这些沙沙作响的东西,都可成为“观念”。在荒芜的桌旁,我凝视书 中的巴赫音乐谱例。其实,这本书里谈论巴赫的部份并非发前人所未发,毕竟作者不是音乐家。不过作者将数学和计算机的想法跟巴赫联系一下,有时别有奇趣。比 如说到巴赫的Hemiola和声,作者说,这是世界的不确定性。说得太简单干脆,让我以为这是我说的,简直想跳起来跟作者争版权。
巴赫的管风琴赋 格作品的结尾,常有这种和声,节奏飘忽地变了一下,很蛮不讲理地把乐意扯到别处,给听者吃了贴迷幻药。那时我就想,上帝为我们设计巴赫这个人物的存在,是 跟量子力学一道给人类准备好的礼物。人秉承牛顿之意似乎把这个世界越算越妥贴,然而最终上帝撕碎我们的信心,毁掉人的骄傲。这一切,真是一种轮回。
依 我看,GEB缺了重要的内容。如果我写,定要加上美国诗人史蒂文斯(Wallace Stevens)。史蒂文斯的诗歌充满荒诞意象,在我看来,往往是是对世界的拓朴式解构,赤裸裸的循环递归迭代,把信仰都绕进去。他喜欢写“一个基督徒女 人”这种题目,更喜欢慢条斯理地细细数来“十三种方式看黑鸟”,喜欢追究“存在”、“记忆”、“消失”。注意,在我看来,这些理念都“后计算机”得不得 了,而且自己丁丁当当搭起概念集合的架子。而且,他的诗意是放射性的,从语词中心出发,从那些华丽怪诞的动物名或者地名出发,最后形成凸多边形——是凸 的,不包括弯弯的蚕豆那样内凹的形状。
我们就这样站在荒岛上,看各种轮回,看船来船往。
Subscribe to:
Posts (Atom)