<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>简单生活@NET &#187; 抽象</title>
	<atom:link href="http://lee.kometo.com/archives/tag/%e6%8a%bd%e8%b1%a1/feed" rel="self" type="application/rss+xml" />
	<link>http://lee.kometo.com</link>
	<description>正确的判断来自经验，但经验往往来自错误的判断</description>
	<lastBuildDate>Tue, 10 Aug 2010 11:01:45 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>从“UML何时死掉”谈起(转)</title>
		<link>http://lee.kometo.com/archives/267</link>
		<comments>http://lee.kometo.com/archives/267#comments</comments>
		<pubDate>Tue, 06 Jan 2009 06:37:01 +0000</pubDate>
		<dc:creator>kometo</dc:creator>
				<category><![CDATA[WEB应用开发]]></category>
		<category><![CDATA[uml]]></category>
		<category><![CDATA[抽象]]></category>

		<guid isPermaLink="false">http://lee.kometo.com/?p=267</guid>
		<description><![CDATA[从“UML何时死掉”谈起 &#8211; 技术开发 &#124; IT168. 【IT168 技术文章】得了一个机会(1)，我问Ivar：“UML什么时候才会死掉呀”。我无意用这个透着促狭味道的问题去为难大师，实在是因为这是我一直以来思考着的问题。向UML之父去求解，自然是最好。 Ivar细毫没有认为我是在为难他，他诚恳的回答让我在那个会议中陷入了深思。他说：“什么时候面向对象死掉了，UML就死掉了”。(2) 一个问题看起来很复杂，但它的答案可能非常简单。一个答案看起来非常简单，但它可能是最正确的。一个正确的答案，也许毫无意义，但也许，那就是大师的答案。 很多我们现在看起来是非常“理所当然”的事情，就曾经困扰着大师们。比如说，我们现在都知道程序的基本逻辑是顺序、分支与循环。那么，“为什么顺序、分支与循环是基本逻辑呢”？“作为基本逻辑，它们充备吗？”谁能回答我？如何回答我？ 这是一个艰深的问题吗？我们知道答案，但即使知道答案，我们也答不出“为什么”。然而，真正的大师们是论证过这个问题的。那个提出“GOTO有害”的大 师Edsgar Wybe Dijkstra（戴克斯特拉/迪杰斯特拉）就为此写了篇“札记”。他是怎么论证的呢？他说计算机可以理解的人的思想方式，有三种。分别是枚举、归纳与抽 象。而，重要的是，Dijkstra进一步的说明，分支(if)是 计算机实现枚举的方法、循环(for)是实现归纳的方法。当他进一步的解释“抽象”时，他说“在现阶段，我发现很难把抽象的作用说得非常清楚”。 Dijkstra大概是做好全部的准备，来完成这篇札记。他通过数学方法来证明了“分支如何以及为什么能实现枚举”。也就是说明分支对于“枚举”这种思 想方法来说，是否是完备的。Dijkstra在写出了大量的数学推理之后，说“上述的笨重证明，也使我自己感到烦恼！但是，在现在，如果真的希望证明这个 程序的正确性，我确实没有更好的办法。”Dijkstra引以为佐证的是，“以前，平面几何里的第一批定理的荒诞证明，也常常使我感到同样的愤怒，因为这 些定理所论证的事情几乎和欧几里得公理自身一样的‘明显’”。 Oh! Dijkstra愤怒的原因，在于原本看起来是如此“显然”、“理所当然”的事情，却需要无比笨重的过程去证明它！如同我们明明知道“1+1＝2”，但证明这一点，既无趣又令人愤恨。 Dijkstra这样的证明过程，奠定了“程序正确性证明”这门学科的基础；它的证明结果，是说明了程序的结构性是有限的，例如顺序、分支与循环。这个 有“结构有限”的理论，开创了“结构化编程”这样的一个时代。我在《代码之美》的序中说“我们如今仍然在这个时代之中而不知觉于这本书的深远影响”，是意 有所指的。因为所谓的“面向对象程序设计”，其根基就是“结构化程序设计 + 在结构上更高层次的抽象”。而这“更高层次的抽象”，就是“对象”。 Dijkstra在1970年前后就完成了这篇札记，而我们接下来这40年的时间，仍未逃离大师最初的思想。然而，对这所有的一切，大师最初创见性的想法可以归结于一句：“可用来理解一个程序的种种思维方法之中，我提及以下三种：枚举法、数学归纳法、抽象。” 为什么是这三种？是不是只有这三种？能不能有更多种？大师没有解释，他只是“提及以下三种”而已。Dijkstra一方面给我们留下了空间，一方面，他足够完备的“论证”说明了基础逻辑必须至少具备“顺序、分支、循环”。而我们，40年来，无有突破。 Ivar把UML之死，归于一种抽象的失败，或其被更高的抽象所替代。实在是无比正确的，因为UML也是建立在结构化、抽象这样一些基元的理论之上。 Dijkstra的那篇札记，被收入《结构程序设计》一书，书里的另外两篇，一篇是“层次结构设计”，讨论的是面向对象程序设计；另一篇是“数据结构札记 ”，讨论的是数据基本抽象。三部文章，三位图灵奖得主，一个跨越40年的时代，以及程序设计语言分类中的1/2（命令式语言）都承受着这种影响。 然而，Dijkstra仍然无法论证，或未曾说明过“三种基础逻辑的唯一性”，他只是想当然地说“我认为”而已。 同样只是从“我认为”开始的，还有图灵机。如果有一个毛头小子跳出来说，“我认为”计算机应该象一个大笨象吃意大利面条；大笨象要有肚子，面条上要打 孔。Oh，很好，这个毛头小子立即会被哄出“计算机科学”的神圣殿堂。问题是，图灵就是这样一个毛头小子。于是他的这一构想就被称为“天才式的创想”。 然而，真的只是这样吗？ 算盘用了几千年，谁问过“算盘为什么能算东西”？算珠、进位、栏，这些东西，是不是基本的存储结构？用算盘的“我们”，是不是计算单元？珠算表是不是运算规则？那些珠子表达出来的“0~9”的排列，是不是输入输出的界面？ “我们+算盘”就是一个完整的计算系统。这个计算系统的完整性，是图灵用了一个假想来说明的。图灵不过是用一个假想描述了一个事实，而这个事实，“看起来”能被机器实现。于是，我们的计算机时代就开始了。 图灵是否证明过“大笨象吃意大利面条为什么是一个完备的计算机系统”呢？不，最初等的问题，往往难于证明。往往，他的证明过程，或应用过程，只是触发了一个想象。 对计算机根本问题的思考，许多会追溯到哲学思想的层面。IOPD和PDIO的问题，程序＝算法+结构的问题等等，就是这一类。还有一些会追溯到人类行为 学、语言学等层面，例如语言、语法、语义，以及有没有语用这样的问题。大多数时候，真正推动了计算机发展的，不是对具体问题的推理求解，而是对问题本身的 抽象。在Dijkstra的叙述中，抽象更象是终极武器。按照Brooks的观点，“数据的表现形式（数据结构，抽象的结果之一）是编程的根本”；按照 Dijkstra的引述，“引用未解释过的名词阐述公理或定理和作用于未解析过的操作数的（命了名的）运算两者之间有着某种平行的相似性”。 无论如何，我们“做一个计算机”，原始的目的不外两个。其一是“让它计算数学”，其二是“让它像人一样思考”。注意，我的确是说“计算数学”，数学是人 类的理论学科，“怎么算”，以及算的内容等等，都是我们自己设定的。而计算机的能力，只是计算“数学”这个它未知的对象而已。事实上，我们现在在讲的“命 令式”，以及“函数式”，或“说明式”，就只是我们为计算机设定的“最基础的运算方式”。在这个“运算系统”中，“数学”并不是最初设定的。 命令式如何计算，函数式如何计算……类似于此的问题了解清楚了，我们对这类语言也就了解了。再谈什么高阶函数（higher-order function）、克里化（Currying）、延续（Continuation），或发生-迭代器（Generator-Iterator）之类，那 已经是具体语言的表象，而非“这一类语言”的本质了。举例来说，JavaScript 1.5还没有实现过“生成器对象(Generator Object)”，但并没有人否认它是函数式语言。反过来说，Generator Object原本就不是函数式语言的必备要素。 LISP表达了函数式语言的全部“必备要素”，然而LISP七个原子运算也是针对于“LIST”这个结构抽象来说的。对于一个“（顺序的）表”，这七个原 子运算是必须的，而对于另一个“（关系的）表”就未必如此了。所以，那这些原子运算，也不必放在函数式的必备要素中。象LUA这样的函数式语言实现方法的 出现，也证明了这一点(3)。 [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://tech.it168.com/a2008/1009/207/000000207460.shtml">从“UML何时死掉”谈起 &#8211; 技术开发 | IT168</a>.</p>
<p><strong>【IT168 技术文章】</strong>得了一个机会(1)，我问Ivar：“UML什么时候才会死掉呀”。我无意用这个透着促狭味道的问题去为难大师，实在是因为这是我一直以来思考着的问题。向UML之父去求解，自然是最好。</p>
<p>Ivar细毫没有认为我是在为难他，他诚恳的回答让我在那个会议中陷入了深思。他说：“什么时候面向对象死掉了，UML就死掉了”。(2)</p>
<p>一个问题看起来很复杂，但它的答案可能非常简单。一个答案看起来非常简单，但它可能是最正确的。一个正确的答案，也许毫无意义，但也许，那就是大师的答案。</p>
<p>很多我们现在看起来是非常“理所当然”的事情，就曾经困扰着大师们。比如说，我们现在都知道程序的基本逻辑是顺序、分支与循环。那么，“为什么顺序、分支与循环是基本逻辑呢”？“作为基本逻辑，它们充备吗？”谁能回答我？如何回答我？</p>
<p><span id="more-267"></span>这是一个艰深的问题吗？我们知道答案，但即使知道答案，我们也答不出“为什么”。然而，真正的大师们是论证过这个问题的。那个提出“GOTO有害”的大 师Edsgar Wybe Dijkstra（戴克斯特拉/迪杰斯特拉）就为此写了篇“札记”。他是怎么论证的呢？他说计算机可以理解的人的思想方式，有三种。分别是枚举、归纳与抽 象。而，重要的是，Dijkstra进一步的说明，分支(if)是<br />
 计算机实现枚举的方法、循环(for)是实现归纳的方法。当他进一步的解释“抽象”时，他说“在现阶段，我发现很难把抽象的作用说得非常清楚”。</p>
<p>Dijkstra大概是做好全部的准备，来完成这篇札记。他通过数学方法来证明了“分支如何以及为什么能实现枚举”。也就是说明分支对于“枚举”这种思 想方法来说，是否是完备的。Dijkstra在写出了大量的数学推理之后，说“上述的笨重证明，也使我自己感到烦恼！但是，在现在，如果真的希望证明这个 程序的正确性，我确实没有更好的办法。”Dijkstra引以为佐证的是，“以前，平面几何里的第一批定理的荒诞证明，也常常使我感到同样的愤怒，因为这 些定理所论证的事情几乎和欧几里得公理自身一样的‘明显’”。</p>
<p>Oh! Dijkstra愤怒的原因，在于原本看起来是如此“显然”、“理所当然”的事情，却需要无比笨重的过程去证明它！如同我们明明知道“1+1＝2”，但证明这一点，既无趣又令人愤恨。</p>
<p>Dijkstra这样的证明过程，奠定了“程序正确性证明”这门学科的基础；它的证明结果，是说明了程序的结构性是有限的，例如顺序、分支与循环。这个 有“结构有限”的理论，开创了“结构化编程”这样的一个时代。我在《代码之美》的序中说“我们如今仍然在这个时代之中而不知觉于这本书的深远影响”，是意 有所指的。因为所谓的“面向对象程序设计”，其根基就是“结构化程序设计 + 在结构上更高层次的抽象”。而这“更高层次的抽象”，就是“对象”。</p>
<p>Dijkstra在1970年前后就完成了这篇札记，而我们接下来这40年的时间，仍未逃离大师最初的思想。然而，对这所有的一切，大师最初创见性的想法可以归结于一句：“可用来理解一个程序的种种思维方法之中，我提及以下三种：枚举法、数学归纳法、抽象。”</p>
<p>为什么是这三种？是不是只有这三种？能不能有更多种？大师没有解释，他只是“提及以下三种”而已。Dijkstra一方面给我们留下了空间，一方面，他足够完备的“论证”说明了基础逻辑必须至少具备“顺序、分支、循环”。而我们，40年来，无有突破。</p>
<p>Ivar把UML之死，归于一种抽象的失败，或其被更高的抽象所替代。实在是无比正确的，因为UML也是建立在结构化、抽象这样一些基元的理论之上。 Dijkstra的那篇札记，被收入《结构程序设计》一书，书里的另外两篇，一篇是“层次结构设计”，讨论的是面向对象程序设计；另一篇是“数据结构札记 ”，讨论的是数据基本抽象。三部文章，三位图灵奖得主，一个跨越40年的时代，以及程序设计语言分类中的1/2（命令式语言）都承受着这种影响。</p>
<p>然而，Dijkstra仍然无法论证，或未曾说明过“三种基础逻辑的唯一性”，他只是想当然地说“我认为”而已。</p>
<p>同样只是从“我认为”开始的，还有图灵机。如果有一个毛头小子跳出来说，“我认为”计算机应该象一个大笨象吃意大利面条；大笨象要有肚子，面条上要打 孔。Oh，很好，这个毛头小子立即会被哄出“计算机科学”的神圣殿堂。问题是，图灵就是这样一个毛头小子。于是他的这一构想就被称为“天才式的创想”。</p>
<p>然而，真的只是这样吗？</p>
<p>算盘用了几千年，谁问过“算盘为什么能算东西”？算珠、进位、栏，这些东西，是不是基本的存储结构？用算盘的“我们”，是不是计算单元？珠算表是不是运算规则？那些珠子表达出来的“0~9”的排列，是不是输入输出的界面？</p>
<p>“我们+算盘”就是一个完整的计算系统。这个计算系统的完整性，是图灵用了一个假想来说明的。图灵不过是用一个假想描述了一个事实，而这个事实，“看起来”能被机器实现。于是，我们的计算机时代就开始了。</p>
<p>图灵是否证明过“大笨象吃意大利面条为什么是一个完备的计算机系统”呢？不，最初等的问题，往往难于证明。往往，他的证明过程，或应用过程，只是触发了一个想象。</p>
<p>对计算机根本问题的思考，许多会追溯到哲学思想的层面。IOPD和PDIO的问题，程序＝算法+结构的问题等等，就是这一类。还有一些会追溯到人类行为 学、语言学等层面，例如语言、语法、语义，以及有没有语用这样的问题。大多数时候，真正推动了计算机发展的，不是对具体问题的推理求解，而是对问题本身的 抽象。在Dijkstra的叙述中，抽象更象是终极武器。按照Brooks的观点，“数据的表现形式（数据结构，抽象的结果之一）是编程的根本”；按照 Dijkstra的引述，“引用未解释过的名词阐述公理或定理和作用于未解析过的操作数的（命了名的）运算两者之间有着某种平行的相似性”。</p>
<p>无论如何，我们“做一个计算机”，原始的目的不外两个。其一是“让它计算数学”，其二是“让它像人一样思考”。注意，我的确是说“计算数学”，数学是人 类的理论学科，“怎么算”，以及算的内容等等，都是我们自己设定的。而计算机的能力，只是计算“数学”这个它未知的对象而已。事实上，我们现在在讲的“命 令式”，以及“函数式”，或“说明式”，就只是我们为计算机设定的“最基础的运算方式”。在这个“运算系统”中，“数学”并不是最初设定的。</p>
<p>命令式如何计算，函数式如何计算……类似于此的问题了解清楚了，我们对这类语言也就了解了。再谈什么高阶函数（higher-order function）、克里化（Currying）、延续（Continuation），或发生-迭代器（Generator-Iterator）之类，那 已经是具体语言的表象，而非“这一类语言”的本质了。举例来说，JavaScript 1.5还没有实现过“生成器对象(Generator Object)”，但并没有人否认它是函数式语言。反过来说，Generator Object原本就不是函数式语言的必备要素。</p>
<p>LISP表达了函数式语言的全部“必备要素”，然而LISP七个原子运算也是针对于“LIST”这个结构抽象来说的。对于一个“（顺序的）表”，这七个原 子运算是必须的，而对于另一个“（关系的）表”就未必如此了。所以，那这些原子运算，也不必放在函数式的必备要素中。象LUA这样的函数式语言实现方法的 出现，也证明了这一点(3)。</p>
<p>函数式还剩什么？</p>
<p>真正理解函数式的秘密，是要一个语言一个语言的学习下去么？是要一种 运算法一种运算法地学习下去么？我们听完人家说“持续”，于是就开始了解持续，而不去问持续为什么出现在函数式里面？亦或是不是函数式的必备要素？还是函 数式运算系统的自身的“问题”？我们正是迷失于种种语言和概念的表象，而最终没能象大师一样去思考“计算机不过是大笨象吃意大利面条”这样的抽象层面的问 题。</p>
<p>我们要改变的是思想，我们要增强的是能力。大多数人只是增强能力，而不改变思想。这就是“我们”——大多数人不是大师的原因。</p>
<p>感谢Ivar。并不仅仅是因为他给出了一个问题的答案，以及他的谦谨和微笑，还感谢他告诉我们：答案并不是表面上的正误，真正的答案是答案背后的思想。</p>
]]></content:encoded>
			<wfw:commentRss>http://lee.kometo.com/archives/267/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
