<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" version="2.0">

<channel>
	<title>4G spaces</title>
	
	<link>http://blog.youxu.info</link>
	<description>I am Eric Xu, a Googler.</description>
	<lastBuildDate>Sun, 03 Mar 2013 16:06:22 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/xumathena" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="xumathena" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>编程珠玑番外篇之番外篇-N  答 UNIX 痛恨者王垠</title>
		<link>http://blog.youxu.info/2013/03/03/unix-haters-2/</link>
		<comments>http://blog.youxu.info/2013/03/03/unix-haters-2/#comments</comments>
		<pubDate>Sun, 03 Mar 2013 15:07:37 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[CompSci]]></category>
		<category><![CDATA[pearl]]></category>

		<guid isPermaLink="false">http://blog.youxu.info/?p=1278</guid>
		<description><![CDATA[(标题是标题党） 王垠最近的一篇文章中，提出了很多有趣的观点。其中最核心的一点，就是 *NIX 系统的设计哲学非常糟糕，而 Windows 系统才是真正为开发者设计的系统。凡是涉及到哲学层面的... ]]></description>
			<content:encoded><![CDATA[<p>(标题是标题党）</p>
<p>王垠最近的<a href="http://bbs.hupu.com/5187888.html">一篇文章</a>中，提出了很多有趣的观点。其中最核心的一点，就是 *NIX 系统的设计哲学非常糟糕，而 Windows 系统才是真正为开发者设计的系统。凡是涉及到哲学层面的争论，最后都是以谁也说服不了谁收场。我相信王垠有足够的理由来证明 UNIX 设计哲学的糟糕，但遗憾的是，他的文章并没有表现出这一点。我摘抄一些论点并作答复。</p>
<blockquote><p>Unix 的 shell，命令，配置方式，图形界面，都是非常糟糕的。每一个新版本的 Ubuntu 都会在图形界面的设计上出现新的错误，让你感觉历史怎么会倒退。但是这只是表面现象。Linux 的图形界面（X window）在本质上几乎是不可治愈的恶疾。</p></blockquote>
<p>以现在的眼光看，X Windows 是一个设计过于繁复的系统。实际上，20年前出版的 The Unix Haters Handbook 里，就有<a href="http://www.art.net/~hopkins/Don/unix-haters/x-windows/disaster.html">专门的一章</a>论述为什么 X Window 的 client-server 架构是糟糕的。可是，这和 Ubuntu 的设计演化之间似乎没有太多关联。Ubuntu 所谓的图形界面设计的错误（以 unity 为例），都是桌面环境层面的问题。一个设计师在这个层面犯错误，就像一个画家因为构图不够工整就去怪画布不行一样，之间还相差不少逻辑链条。</p>
<p>X Window 和其他操作系统上的 GUI 系统最大的不同，是它和宿主操作系统的松耦合。因为这种松耦合的存在，在不需要图形界面的地方，操作系统可以不带 X Window。很多云服务的服务器，都是没有 X 的。当下如日中天的移动操作系统如 Android 和 iOS 都是 UNIX 家族操作系统，而这两者都没有用 X Window 提供 GUI 支撑，而是另外开发了一套专门适合触摸式移动设备的图形界面系统。图形系统和操作系统间的松耦合，使得操作系统可以从头搭建适合具体设备的图形界面交互(如 Cocoa Touch)，并且快速的迭代（如 Project Butter）。</p>
<p>在 GUI 和内核的耦合关系上，架构的确决定了产品的形状。我们都知道，微软 NT 内核和 Widnows UI 系统是绑定在一起的。Windows Phone 8 要和 Windows 8 共享内核和其他组件的结果，就是它们都必须兼顾桌面和移动平台。为此，微软做出了两个可以做榔头也能做螺丝刀的东西。一个是 Windows 8，支持触摸屏，Modern UI 界面长得像手机界面；一个是 Windows Phone 8，界面很适合触摸设备，却又同时支持移植来的桌面程序，造成有的程序界面长得像桌面。无论你认为哪个操作系统的图形界面漂亮，哪条路更加有光明的未来，微软的这些系统之间的关系之繁复，开发迭代的周期如此之长，都是客观事实。</p>
<p>UNIX 系统的Unix 的 shell，命令，配置方式的确有不少的问题，在痛恨者手册里也有详细的论述，<a href="http://blog.youxu.info/2011/10/14/notes-on-the-unix-haters-handbook/">我以前也写过</a>，就不一一列举了。</p>
<blockquote><p>Unix 依靠自己的“宗教”和“哲学”，“战胜”了别的系统在设计上的先进，统治了程序员的世界。胜者为王，可是 Unix 其实是一个暴君，它不允许你批评它的错误。它利用其它程序员的舆论压力，让每一个系统设计上的错误，都被说成是用户自己的失误。其它系统里面某些优秀的系统设计，也许就要被历史掩埋……</p></blockquote>
<p>一个操作系统，是不可能凭着“宗教”和“哲学”就能统治程序员的世界的。程序员不是天主教徒，UNIX 也不是程序员世界的教皇。实际上，所谓的 UNIX 系统，不是一个特定的系统，而是一个家族的系统。这个家族的系统包罗万象。不喜欢微内核的做了宏内核，不喜欢一切还不都是文件的做了 Plan 9, 不喜欢 X Window 慢如蜗牛的做了 XGL 加速。优秀的设计不断地加入这个系统，改造这个系统。UNIX 来源于 Bell 实验室，X Window 却是 MIT 的，BSD 来自于 Berkeley, Solaris 来自于 SUN, Mac OS 来自于 Apple。如果说这里面有宗教的话，这一定是世界上最诡异的宗教，里面的教徒还天天打架。</p>
<p>在 UNIX 系统中，所有的设计，都在开放的环境下竞争。我们可以说 UNIX 不是一个设计良好的系统，但是它的设计哲学在竞争中获胜的原因，不是因为它是“暴君”，控制了程序员的思想，而恰恰是因为它的开放，所以最终汇总了很多优秀的东西。至于 UNIX 这种不怎么好的系统为何最终获胜，<a href="http://www.jwz.org/doc/worse-is-better.html">20年前的一篇文章</a>也讲得很清楚了。</p>
<blockquote><p>因为 TeX 的语言是非常糟糕的设计。它的设计者几乎完全不明白程序语言设计的基本原则，不明白什么叫做“抽象”。</p>
<p>而这些源于 Unix 的工具却像是“魔鬼棋”或者“三国杀”，有太多的，无聊的，人造的规则。有些人鄙视图形界面，鄙视 IDE，鄙视含有垃圾回收的语言（比如 Java），鄙视一切“容易”的东西。他们却不知道，把自己沉浸在别人设计的繁复的规则中，是始终无法成为大师的。就像一个人，他有能力学会各种“魔鬼棋”的规则，却始终无法达到象棋大师的高度。</p></blockquote>
<p>这里，王垠把两个不相关的东西放到了一起。一个是工具的设计哲学，一个是我们如何学习知识。魔鬼棋本身是一种工具设计哲学，和成为大师无关。</p>
<p>在<a href="http://blog.youxu.info/2012/02/02/software-tools-1/">军刀工具</a>一文中我提过，面向特定领域的软件工具之所以让人觉得复杂，是因为这个问题本身复杂。我们把解决特定领域问题而所需的知识叫做”领域模型“(domain model)。如果我们不了解领域模型，就不能理解为什么 Photoshop 比系统自带的 Paint 复杂几千倍, 或者为什么我们需要正则表达式这种诡异的东西。我们讲的复杂与简单，都是工具设计哲学层面的。</p>
<p>以王垠说的 TeX 为例。写出《计算机程序设计艺术》的 Knuth 到底知不知道程序语言设计的基本原则我们可以不加讨论。了解一点字体设计和排版的都知道，计算机排版问题是个复杂的问题。的确，软件工具的设计目标，是把复杂的问题简化。然而，大多数人不知道的是，简化问题是一个两步过程。第一步，我们需要把现实的问题映射到一个领域模型。第二步，是把这个模型简化到我们人可以处理的地步。很多时候这两步合并起来了，让我们觉得这两步好像是一步，并且认为所有的设计，都应该朝简化的方向走。这是一个对设计的错误认识。</p>
<p>举个非计算机领域的例子：用电饭锅煮饭非常简单，加米加水再按个按钮就行了。电饭锅的设计者的设计目标是操作简单且能完美地煮米。作为工具的设计者，它一方面需要了解大米是怎么煮熟的，另一方面需要提供给用户一个简单的按钮。TeX 作者，从一开始就不是设计一个电饭锅，而是一个精确的温控炉子。有了这个精确的温控炉子，想烧饭的可以把它封装成电饭锅，想做蛋糕的可以把它封装成蛋糕烤箱。设计电饭锅的人的设计，并不比设计精确的温控炉子的人好，或者差。设计者的初衷决定了产品的形状。 Kunth 的初衷，正是设计一个可以让他人排版出任何想排版的东西的系统。也就是说，做出一个最终非常简单的，只有一个按钮的排版系统不是他的设计目标。做出一个可以高度定制的系统才是他的目标。</p>
<p>其实，TeX 本身也是一个由繁到简的软件系统。它把所有排版中的问题，都提炼成了一些控制原语。有了这些控制原语，针对特定领域做优化就不是问题了。现在通用的科学出版排版工具 LaTeX, 正是这样的一种优化。这是有心设计的结果。我们抱怨 TeX 复杂，其实是抱怨排版本身复杂。Windows 系统上有许多排版软件，可以毫不客气地说，没有一个可以达到 TeX 所能到达的精确控制。以此责怪 UNIX 下的软件工具是魔鬼棋，就类似于责怪 Photoshop 为啥不象 Paint 那样简单一样，有选择性地忽视了两者所要解决地问题不一样。</p>
<p>我欢迎所有的 UNIX 使用者加入痛恨者阵营，因为我也是 UNIX 痛恨者。只有成为了 UNIX 痛恨者，你才是一个真正的 UNIX 使用者。至于 Windows, 我们对它没有感情，无所谓爱恨。</p>
<div id="google_plus_one"><g:plusone></g:plusone></div><img src="http://feeds.feedburner.com/~r/xumathena/~4/B7GuvvbYLK8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.youxu.info/2013/03/03/unix-haters-2/feed/</wfw:commentRss>
		<slash:comments>54</slash:comments>
		</item>
		<item>
		<title>佛教艺术中的沙</title>
		<link>http://blog.youxu.info/2012/10/24/sands-in-buddhism/</link>
		<comments>http://blog.youxu.info/2012/10/24/sands-in-buddhism/#comments</comments>
		<pubDate>Thu, 25 Oct 2012 03:07:35 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[Life]]></category>
		<category><![CDATA[Art]]></category>
		<category><![CDATA[Zen]]></category>

		<guid isPermaLink="false">http://blog.youxu.info/?p=1266</guid>
		<description><![CDATA[“沙”　是佛教里很值得一提的物件，很多佛教艺术都和沙有关。 日本禅宗的“枯山水”就是一种依赖于沙的园林艺术。枯山水在西方很有名，以至于在西方直接被称为禅花园(Zen Garden)。一般... ]]></description>
			<content:encoded><![CDATA[<ul>
<li>“沙”　是佛教里很值得一提的物件，很多佛教艺术都和沙有关。</li>
</ul>
<p>日本禅宗的“枯山水”就是一种依赖于沙的园林艺术。枯山水在西方很有名，以至于在西方直接被称为禅花园(Zen Garden)。一般的园林都会通过假山和水构景，通过人造的山和水，来引起观者自然的联想，从而联系人与自然。而枯山水园林却反其道而行，不采用真正的山，也不摆放真实的树，竹等物。枯山水中的水，是细细耙制的静态的白色砂石，模拟水的动态形态；枯山水中的植物也极少或者没有。这种美学上的差异，其实是和中日两国禅宗在修行上的侧重不同有关的。</p>
<p><a href="http://blog.youxu.info/wp-content/uploads/2012/10/360px-Daisen-in2.jpeg"><img class="alignleft size-medium wp-image-1268" src="http://blog.youxu.info/wp-content/uploads/2012/10/360px-Daisen-in2-225x300.jpg" alt="" width="225" height="300" /></a>中国禅宗传统上就是位于名山大川，因此在修行时秉承了一种自然主义的路线，让修行者在见山是山，见水是水的自然景观或者园林中修行。日本的禅宗主要继承了曹洞和临济两家。曹洞侧重于打坐和冥想，即“只管打坐”（<em>Shikantaza</em>)。临济强调&#8221;心即是佛&#8221;，也是促使人向内求索。在这种思想指导下，园林就不再坚持自然主义，而转为为修行着提供安心之法。枯山水正是这种哲学的体现。一个枯山水园林一旦建成，一年四季景色完全相同，恒久不变，宁静无碍。在枯山水中修行，心不会四处乱走。</p>
<p>枯山水是用静态景观来展现这个大千世界动态的一瞬间，而藏传佛教里的坛城沙画 (<em>Sand Mandala)</em>，则是用动态的构建，来展现万事无常这个恒久不变的佛理。构建坛城沙画的目的，不是为了让它成为一项艺术品，而是为了最后摧毁它。这种最终什么也得不到的艺术创作，正是说明了佛教里一切无常的道理。</p>
<p>佛教的艺术家很早就意识到沙是彩色的。《大方广佛华严经》就提到过四条不同的大河流出不同颜色的细砂：“恒伽河口流出银沙，私陀河口流出金刚沙，信度河口流出金沙，缚刍河口流出琉璃沙”。结合华严经所说的恒河沙中的世界，用彩色的沙构建大千世界这种佛教艺术的出现是自然的。</p>
<p>为了构建坛城沙画，喇嘛们需要用尺子和圆规仔细的规划沙画的基本结构和几何形态。同时，所有的彩色沙都是仔细遴选甚至磨制而成。这些彩色的细沙被装入一个小口沙漏，然后由有经验的喇嘛，将这些细沙细细铺出。构建沙画是费时费力的，往往需要众多喇嘛们连续好天的工作。而不管花多少力气，多么美丽的沙画，只要沙盘倾覆，都一瞬间化为无形。从这个意义上来说，要揭示世事无常的道理，没有沙更加贴切的道具了。</p>
<div id="attachment_1269" class="wp-caption alignright" style="width: 310px"><a href="http://blog.youxu.info/wp-content/uploads/2012/10/320px-Amazing_sand_mandala.jpeg"><img class="size-medium wp-image-1269" src="http://blog.youxu.info/wp-content/uploads/2012/10/320px-Amazing_sand_mandala-300x225.jpg" alt="" width="300" height="225" /></a><p class="wp-caption-text">坛城沙画</p></div>
<p>坛城沙画一旦建立，它的唯一命运就是被摧毁。高级别的喇嘛会先诵经一段，然后以一定的规则将沙画摧毁，将各色细沙汇作一堆，装入瓶中，撒入江河。就像熵只能增加一样，美丽的沙画的每一次破坏都是不可逆的。这种摧毁美丽艺术品的悲剧感和无力感，正是佛教想要说明的道理：诸行无常，是生灭法，生灭灭已，寂灭为乐。</p>
<p>佛经里对沙的数量，沙的色彩和沙的无常感都有论述。有趣的是，尽管大多数人认为“一花一世界，一沙一凡尘”出自于佛经，实际上佛经中从来没有明确的提出过这个论题。这个很有佛学意味的句子，实际上来自于英国诗人<em>William Blake</em> 的《纯真预言》：</p>
<blockquote>
<div>To see a world in a grain of sand,<br />
And a heaven in a wild flower,<br />
Hold infinity in the palm of your hand,<br />
And eternity in an hour.</p>
<div></div>
</div>
</blockquote>
<div id="google_plus_one"><g:plusone></g:plusone></div><img src="http://feeds.feedburner.com/~r/xumathena/~4/g2fAnN0I4Bs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.youxu.info/2012/10/24/sands-in-buddhism/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>SpaceX 开创了人类航天的新纪元</title>
		<link>http://blog.youxu.info/2012/05/22/spacex/</link>
		<comments>http://blog.youxu.info/2012/05/22/spacex/#comments</comments>
		<pubDate>Tue, 22 May 2012 10:42:02 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[aerospace]]></category>
		<category><![CDATA[tech]]></category>

		<guid isPermaLink="false">http://blog.youxu.info/?p=1259</guid>
		<description><![CDATA[今天，美国一家私人公司 SpaceX 成功的从美国佛罗里达州肯尼迪航天中心火箭的空军发射场发射了一颗火箭，这颗火箭的终点，是国际空间站(ISS)。这是继上次成功发射并回收卫星后，一家私人... ]]></description>
			<content:encoded><![CDATA[<p>今天，美国一家私人公司 SpaceX 成功的从美国佛罗里达州肯尼迪航天中心火箭的空军发射场发射了一颗火箭，这颗火箭的终点，是国际空间站(ISS)。这是继上次成功发射并回收卫星后，一家私人公司首次将载荷送到国际空间站附近。自美国的航天飞机退役后，能够将载荷运输到国际空间站的方法只有一个&#8211;俄罗斯的联盟号飞船。而现在，私人航空已经离这个目标不远了。</p>
<p>SpaceX 的成功是美国社会一直引以为豪的企业家精神和创新精神的成功。2002 年，eBay 以 15 亿美元的价格购买了 PayPal，一家从事电子支付的公司。很多 PayPal 的员工一夜之间成为亿万富翁、PayPal 的共同创始人　<a href="http://en.wikipedia.org/wiki/Elon_Musk">Elon Musk</a>　极具冒险精神，眼看 PayPal 已近逐渐成熟，便在 2002 年 eBay 收购还没定型之前，马不停蹄的创立了一家叫做 SpaceX 的公司，致力于民用航天探索。</p>
<p>和 Jobs 用自己的钱投资 NeXT 和 Pixar 一样，Musk 将自己口袋里的 １亿美元投给了 SpaceX。当时，Musk　同时主持两家创业公司，一家是 SpaceX，从事空间探索，另一家是 TelsaMotor，从事电动汽车生产。这两家公司都不是传统的软件或互联网公司，因为空间探索和生产汽车的成本，无需多说，公司的烧钱的速度远远快于硅谷的其他创业公司。可以想象，这两家公司在发展过程中屡屡不绝的资金不足的问题。最后问题严重到需要　Musk　将自己口袋里仅存的 70 万美元拿出来发工资的地步，这在投资人遍地的硅谷是非常少见的事情。</p>
<p>如果换到其他创业者，到了这种地步，可能唯一的路就是缴械投降了。和 Steve Jobs 一样， Musk 的过人之处之一，就在他不但毫不畏惧风险，而且还能说服别人和他一起冒险。通过与 PayPal 一帮一夜暴富的富翁之间的关系，SpaceX 从一家创业基金拿到了一笔钱，暂时保证了公司不会关门大吉。同时，他加快了说服军方和NASA与 SpaceX 签订合同的谈判。2005 年，在 SpaceX 最紧要的关头，美国空军与 SpaceX 签下了价值一亿美元的发射合同。随后，2006年，NASA　与 SpaceX 又签订了价值１０亿美元的向国际空间站运送补给的合同。这些合同带来的巨额项目投资，使SpaceX 终于摆脱了市场和资金的两大问题，成为民用航天的一家标杆，此后就是大家熟知的火箭发射，卫星回收等历史了。而 Musk 在 TeslaMotor 一侧的成功也非常耀眼。该公司是第一家量产锂电池汽车的公司，并在 2010 年成功上市。就像当年 Jobs 同时运营两家公司最后让 Pixar 上市一样。</p>
<p>SpaceX 用很少的钱，在极短的时间里完成了某些号称体制优越的国家举国都不能完成的事情（我说朝鲜呢，不许联想），最重要的当然是 Musk 的远见，无数的工程师杰出贡献。这里，美国政府和 NASA, 也起到了锦上添花的作用。美国政府不敢擅自夸耀自己，但公平的说，SpaceX 的成功离不开美国的航天政策调整。</p>
<p><a href="http://blog.youxu.info/2010/09/30/nasa-next-generation-space-progra/">美国政府在空间探索上的策略</a>虽然一个总统一变，但因为 NASA 具有较大自主性，因此空间政策大体上还是很有政策的延续性的。因为航天飞机的退役日程，小布什政府一直在规划如何在航天飞机退役后继续维护国际空间站。当时小布什政府的设想是一箭双雕，既要国际空间站，又要重返月球。这样，NASA　就提交了一个双火箭的星座计划。因为该计划预算巨大，而美国政府又面对巨大的预算压力，因此联邦政府要求　NASA　同时也寻找其他替代方案，而 SpaceX 的火箭和龙舱，即在当时被　 NASA 选中。</p>
<p>奥巴马政府的空间政策比小布什政府更有远见。因为预算问题，奥巴马政府取消了星座计划的登月部分。NASA 内部的一些专家早就预言过，现在已经不是冷战时期，美国公众根本不想和中国比赛登月。如果美国想再次登月，就要消减国际空间站。而且即使美国登月，中国不会因为美国再次登月了就放弃登月，所以美国和中国竞赛登月连政治意义都没有，美国就应该放弃登月。奥巴马政府采纳了这样的建议，让NASA跳过月球，除国际空间站外，把眼光放在 James Webb 太空望远镜等太阳系尺度的空间探索上。因为这样的政策调整，NASA　得以缓出人员和精力从事更加深度的空间探索，而将给国际空间站运输货物这样“技术含量较低”的项目，交给 SpaceX 这样的私人公司完成。NASA 和美国政府都不顾及所谓的面子问题，在航天飞机退役后，委托俄罗斯用联盟号飞船运送美国宇航员和货物。从短时间来看美国好像丢了人，而长时间来看，是省了NASA的预算，并给了 SpaceX 等私人航天巨大的成长空间（美国私人航天领域公司很多，不限于 SpaceX，SpaceX 是领跑者）。</p>
<p>按照 NASA 的计划，SpaceX 需要先将龙舱发射到国际空间站附近，伴随飞行。然后下一步设计出能够于国际空间站对接的龙舱，最终完成飞行，对接，分离的三步目标。随着 SpaceX 的成功发射，未来已经离我们不远，航天历史正在翻开新的一页。</p>
<p>&nbsp;</p>
<div id="google_plus_one"><g:plusone></g:plusone></div><img src="http://feeds.feedburner.com/~r/xumathena/~4/HCgPT4LxAy8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.youxu.info/2012/05/22/spacex/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>编程珠玑番外篇 -M. 软件工具的设计哲学1</title>
		<link>http://blog.youxu.info/2012/02/02/software-tools-1/</link>
		<comments>http://blog.youxu.info/2012/02/02/software-tools-1/#comments</comments>
		<pubDate>Fri, 03 Feb 2012 01:04:44 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[CompSci]]></category>
		<category><![CDATA[pearl]]></category>

		<guid isPermaLink="false">http://blog.youxu.info/?p=1243</guid>
		<description><![CDATA[我们通过工具的设计者和使用者的视角观察工具，讨论工具背后的设计哲学和对应的学习曲线。 设计者和使用者 从某种意义上来说，工具是个联系使用者和设计者的桥梁。工具的设计者为解决... ]]></description>
			<content:encoded><![CDATA[<p>我们通过工具的设计者和使用者的视角观察工具，讨论工具背后的设计哲学和对应的学习曲线。</p>
<p><strong>设计者和使用者</strong></p>
<p>从某种意义上来说，工具是个联系使用者和设计者的桥梁。工具的设计者为解决一类问题而设计工具，工具的使用者也是为了解决一类问题而使用工具的。这两者对于工具都有自己的理解。工具的设计者通常会预测此工具会被用来解决怎样的问题，在设计工具时预见使用者的偏好，而工具的使用者则根据所面临的问题选择合适的工具。</p>
<p>在理想情况下，设计者和使用者对问题的理解 (Vision) 是类似或者重叠的。这时候，工具的设计者能够完全理解使用者的需求，而使用者完全理解这个工具的长处和短处。成语“得心应手”说的就是这样的一种情况：掌握了一样工具，因此使用起来非常顺利。</p>
<p>在现实中，设计者和使用者对问题的理解可能是有差异的，随之对工具的使用方法的理解也有所不同。有时候，工具的使用者能够将工具用到远超出设计者想象的地步。有两个著名的例子可以说明这个问题。第一个例子是出自 Bell 实验室的 AWK 语言。从 AWK 的三位作者的角度看，这是一个与 sed 互补的，处理文本记录的语言。而AWK在贝尔实验室内部推广开来后，三位作者发现其他团队用 AWK 来写作大的数据管理系统，而三位作者本人从来没有写过超过一百行的 AWK 脚本。第二个例子是 C++ 的模版　(template)。模版的设计者的初衷是让 C++ 在处理对象时更加灵活，而自从C++模版的图灵完全特性被发现后，写作一些通用的库成为可能。如C++的Boost库，即重度依赖于模版。设计模版的人未必想到 Boost 库那样对模版的奇妙运用。这两个例子，都充分说明了工具的设计者未必能够充分体验到自己设计的工具的强大之处。</p>
<p>另一种情况是工具的设计者是解决问题的专家，对问题有深刻的理解，而工具的使用者则没有能够完全体验到工具的强大。工具的使用者因此需要学习如何使用工具，学会像工具的设计者那样思考，从而领略到工具的强大之处，达到得心应手的地步。对于完成学校教育后的成人来说，大多数学习都是在学习工具的使用。那么，如何学习软件工具呢？</p>
<p>在我看来，虽然工具千差万别，学习工具的用法也大相径庭，不过如果细细总结，工具的设计者所奉行的套路无非就两种，所对应的学习方法也有两种。我把这两种设计讨论形象地称为<strong>瑞士军刀</strong>和<strong>工具链</strong>。这两种设计哲学背后的假设，以及相应的学习曲线是不同的。</p>
<p><strong>设计者的哲学一：瑞士军刀</strong></p>
<p>瑞士军刀以方便著称，一把军刀包含了很多小部件，配合使用能够解决很多野外生存问题。不少计算机工具借用了这个类比。在Google 上搜索 “The swiss army knife of”　会发现很多软件工具号称某领域的瑞士军刀（见表一）</p>
<div dir="ltr">
<table border="1">
<colgroup>
<col width="*" />
<col width="*" />
<col width="*" /></colgroup>
<tbody>
<tr>
<td>工具名称</td>
<td>用途领域</td>
<td>广告词</td>
</tr>
<tr>
<td>BusyBox</td>
<td>嵌入式 Linux 命令集</td>
<td>The Swiss Army Knife of Embedded Linux</td>
</tr>
<tr>
<td>Perian</td>
<td>Apple QuickTime 组件管理</td>
<td>Perian &#8211; The swiss-army knife of QuickTime® components</td>
</tr>
<tr>
<td>Sox</td>
<td>音频文件编辑</td>
<td>The Swiss Army knife of sound processing programs</td>
</tr>
<tr>
<td>Netcat</td>
<td>TCP/IP 数据包分析</td>
<td>TCP/IP Swiss Army Knife</td>
</tr>
<tr>
<td>FFMpeg</td>
<td>视频和视频流文件编/解码</td>
<td>The swiss army knife of Internet Streaming</td>
</tr>
<tr>
<td>Kanif</td>
<td>计算机集群管理</td>
<td>Cluster management and administration Swiss Army knife</td>
</tr>
</tbody>
</table>
</div>
<p>从表一我们不难发现，这些宣称为“瑞士军刀”的工具有一个共同特点：都是针对某个特定领域的问题而设计的。这一点和瑞士军刀是相似的。瑞士军刀的多功能，并不是指这是一把砍树修桥盖房子的万能刀，而是说在野外生存这个领域内，军刀能够解决许多问题。回到表一，用过这些工具的读者一定有所体会：这些工具解决所在领域的复杂问题的能力是非常强的。比如，FFMpeg 内置多种视频编、解码器，众多格式能够相互转换，支持的视频编码格式比任何商业软件都要多。这些优势让 FFMpeg 几乎能解决所有现实中遇到的视频处理问题。因为这些工具针对特殊领域，且功能强大，用瑞士军刀做比喻是很形象的。</p>
<p>除了自称为“军刀”的这些工具外，还有许多耳熟能详的工具属于此类。如平面设计软件 Photoshop，是融许多复杂图像算法和插件于一体的图像处理之瑞士军刀；GNU 的 GCC 编译器，是集语法分析，代码优化，代码生成等功能于一体的专门负责程序编译的瑞士军刀。这些软件包的内部结构，都不是一个单一的程序，单一的部件，而是一揽子的部件，一箩筐的功能模块。</p>
<p>瑞士军刀巧妙地将众多小工具紧凑地组合到了一起。同样，我们说的军刀工具的一大优雅之处也是类似的，即通过一个统一的控制界面，将这一揽子的部件有机地组合在了一起。设计模式里，这种组织功能的方式称作为 Facade 模式，具体指以一个命令或者一个统一的界面抽象内部复杂的操作。如 FFMpeg 和 GCC 这样几乎无所不能的软件包，都可以通过一个单一的命令 (ffmpeg 或 gcc) 加不同的参数调用。在 GUI 程序的世界，所有的 Photoshop 插件都可以通过 Photoshop 的图形界面菜单调用。Facade 模式隔开了用户和“军刀&#8221;工具复杂的内部逻辑，让用户从一个&#8221;抽象&#8221;的层面理解工具。正如我们开车并不一定要了解引擎是怎么工作一样，工具的使用者不需要关系这些工具的内部是如何运转的。</p>
<p>总结这类工具的特点，瑞士军刀是一种把各种工具组合到一起，一起解决一个复杂问题的设计哲学。核心是。设计模式里的facet 模式，一个领域的问题，而不是一个特定的工具。这里实际上是一类工具，而非一个单独的工具。这一类工具被精巧地安排在一起，对外提供一个一致的服务接口，让用户以简单的控制方式完成相对复杂的任务。</p>
<p><strong>领域知识假设和学习曲线</strong></p>
<p>“瑞士军刀“工具都是面向特定领域的。无论是图片，视频处理，还是查看TCP包信息，这些工具都假设了使用者知道图片处理，视频处理或者TCP包的结构等知识。心理学上把这些为了解决特定领域问题而所需的知识叫做”领域模型“(domain model)。工具的设计者是不负责教授这些知识的。因此，作为工具的使用者，掌握这些特定领域的知识就成了使用工具的前提。一般的软件都是基于领域模型的。比如，平面图形处理工具 Photoshop 假设图片是个多层次的物体，如果我们不了解这个模型，就完全不知道为啥这个软件为啥比系统自带的 Paint 复杂几千倍。</p>
<p>因为军刀背后蕴含着领域知识假设，学习军刀工具就不仅仅是学习工具的使用本身，而是学习背后的领域知识。如果不了解背后的领域知识，即使我们会操作这样工具，依然谈不上是个熟练的使用者。相信诸位读者都属于“懂计算机”的一类人。现实中，我们这类人常常因为“懂计算机”，而被家人和朋友要求编辑图像，做个视频或者做个网页等等。有些要求还特别专业，让只会写程序的人非常吃力。究其原因，是因为程序员群体掌握的，只是编程的领域知识。如图像，视频处理所需要的领域知识，均是编程之外的了。即使像 Eclipse 这样专门给程序员用的软件，也隐含假设了使用者需要重构，设计模式等等的知识。不掌握这些知识的程序员用 Eclipse 也仅仅是将其当成一个花哨的编辑器使用而已。</p>
<p>因为需要领域知识做铺垫，军刀工具的学习曲线是因人而异的。对于有的人来说，如果本来就知道工具背后的假设，学习计算机操作就毫不费力。以我爸爸为例，本身用计算机并不熟练，但他学过画画，作图感一流，若干年前从书店随便买了一本 Photoshop 入门后就把 Photoshop 玩得很熟。而我知道这个软件每个选项的意义，却处理不出什么像样的图。对于我爸来说，他的学习曲线就很平缓，而对于我来说，就很陡峭。</p>
<p>学习曲线不一样这一点在计算机语言的学习上尤为明显（计算机语言是众多编程特性的大糅合，是典型的军刀设计）。像 Google 这样的公司面试时完全不考察语言细节，很多人入职的时候都不会 Java。因为我们相信任何合格的程序员都能很快学会 Java 这个语言。道理很简单，只要考察一个人掌握了Java 语言背后的领域知识，即面向对象的设计，数据结构，控制结构等等，就有充分理由相信这个人学 Java 毫不费力。但是，话说回来，每个语言背后的领域假设都有细微的差别。比如 Lua 只支持哈希表，Awk 支持哈希表也支持记录处理，Vim 里一切都是文本对象等等。真的领会这些领域模型并且将这些语言用得纯熟，没有长时间的投入是不可能的，这就是为何 Peter Norvig 强调“十年学会程序设计”。这两种对待编程语言的态度是不矛盾的。引申出来，对于语言或者工具的初学者来说，要分情况学习军刀工具。在不熟悉领域知识的情况下，应该找一本非常简单的书熟悉领域模型，获得一个 Big picture，而非上来就想着要解决手头的问题。而对于已经熟悉领域模型的人，比如会了一个 MVC 框架再学另一个的人，随便捡起一本 In Action 或者 Cookbook 也能事半功倍；有人甚至书都不需要买，看看文档就可以了。不清楚内情的可能会把这类人叫做强人，其实了解了背后的底细后，所有人都可以如此。</p>
<p>最后谈一下军刀工具的设计策略。我们说了，军刀工具背后蕴含的是领域知识。因此，设计军刀工具的人，必然需要是对问题有深刻理解的领域专家。这一点很好理解，因为很难想象一个不懂图像处理的人会指导 Photoshop 的设计，或者一个不懂统计的人会设计 R。不过，即使是最资深的专家，也未必能设计出一个能覆盖到所有问题的工具。这时候，工具的扩展性就成了一个重要的考量。可以这么说，几乎所有成熟的军刀工具，最后一定会进化出一个插件系统，用以扩展功能。插件系统的好与坏是考验设计者功力的时候。像 Firefox 和 Photoshop 这样的工具，若不是第三方插件，至多是一个普通的软件。加入插件系统后，这些工具成为了一个平台，从而衍生出了无数的新用例。即使像功能小巧和 Emacs 格格不入的 Vim, 最终也进化出了插件系统。这是一样工具成熟的体现。</p>
<p>总结一下军刀工具的特点如下：</p>
<ul>
<li> 面向特定领域，覆盖该领域大部分问题</li>
<li>由领域专家设计，使用者需要了解该领域的基本知识才能熟练运用工具</li>
<li>内部由众多小模块组成，对外提供一致，简单的控制界面</li>
<li>常常具有强大的插件系统，以方便用户扩展现有系统</li>
</ul>
<div id="google_plus_one"><g:plusone></g:plusone></div><img src="http://feeds.feedburner.com/~r/xumathena/~4/QzGcpobuSGU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.youxu.info/2012/02/02/software-tools-1/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>编程珠玑番外篇 -L. Plan 9 管道工的启发</title>
		<link>http://blog.youxu.info/2011/11/24/plan-9-plumber/</link>
		<comments>http://blog.youxu.info/2011/11/24/plan-9-plumber/#comments</comments>
		<pubDate>Fri, 25 Nov 2011 02:50:01 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[MacOSX]]></category>

		<guid isPermaLink="false">http://blog.youxu.info/?p=1239</guid>
		<description><![CDATA[Smalltalk 作者 Alan Kay 曾说过，对象不是 Smalltalk 的本质，对象间的消息传递才是。对于操作系统中的基本对象&#8211;进程，类似的说法也是成立的：进程不是操作系统的本质，进程间的通信才是。... ]]></description>
			<content:encoded><![CDATA[<p>Smalltalk 作者 Alan Kay 曾说过，<a href="http://lists.squeakfoundation.org/pipermail/squeak-dev/1998-October/017019.html">对象不是 Smalltalk 的本质，对象间的消息传递才是</a>。对于操作系统中的基本对象&#8211;进程，类似的说法也是成立的：进程不是操作系统的本质，进程间的通信才是。像 <a href="http://en.wikipedia.org/wiki/Mach_(kernel)">Mach</a> 这样的微内核操作系统的全部，就是一个供进程传递消息的框架。</p>
<p>进程间通信的技术细节繁杂，以Linux 系统为例，就有文件，管道，消息队列，信号量，RPC，UNIX Socket,　RPC　等等多种方式。Windows 系统还有邮件槽, COM 对象等等。Mac OS 则有 AppleEvent 等等。在这里我们介绍 Plan 9 系统中一个不太为人所知的 IPC 机制：<a href="http://swtch.com/plan9port/man/man4/plumber.html">Plumber</a>，或者叫做管道工。我在&#8221;<a title="Permanent Link to 开发人员为何应该使用 Mac OS X 兼 OS X 小史" href="http://blog.youxu.info/2010/02/28/why-mac-os-x-for-programmers/" rel="bookmark">开发人员为何应该使用 Mac OS X 兼 OS X 小史</a>&#8220;中曾赞扬过 Mac OS X 系统中的 AppleEvent 进程间通信机制对工作效率的提升。和AppleEvent 类似，管道工也是对图形界面下进程间通信的一个尝试，不过在通信的粒度上有所区别。</p>
<p>我们从一个简单的例子入手。在如今网络普及的时代，几乎所有的软件都能自动识别链接。只要打入 http:// 开头的一串字符，就立即转化为一个可点击的链接，点击这个链接则自动召唤出浏览器。我们对此毫不感到新鲜，因为这功能再自然不过。其实这些功能在上世纪９０年代还是很少见的。 Plan 9 的管道工，在当时就前瞻地提出一套匹配字符串和自动投递给指定应用程序的机制。我们只需要告诉管道工，用户选中字符串匹配某类型的时候就交由某应用程序处理，管道工即负责具体的程序间的通信。这是对 UNIX　管道机制的一个革新。如我在Mac OS 一文中所说，纯粹的管道机制在图形界面程序中已经不再适用了。</p>
<p>我们所熟悉的URI 处理仅限于浏览器，且只能处理由 RFC 2396 预先定义的 URI 模式。即便如此，我们也能体会到 URI 处理器的方便。像大家熟悉的电驴链接实际上是 ed2k:// 打头的 URI。在浏览器点击后就自动用电骡打开；苹果的 iTunes 的链接实际上是 itms: 打头的 URI；Android 商店的链接其实是 market:// 打头的 URI 等等，都是让用户更加方便的例子。有了这些机制后，我们难以想象没有这些机制而需要拷贝粘贴的日子是如何度过的。</p>
<p>管道工是 URI 处理器的推广形式。在管道工里，不仅仅是 URI，一切的字符串都可能匹配。因为读者可能没有用过管道工，我们仍然以大家熟悉的例子来说明。安装了 Skype 浏览器的插件会自动把网页上的电话号码变成一个特殊的“用 Skype 拨打该电话”的按钮，在 Gmail 里开启一些插件后 FedEx 和 UPS 的包裹号码能自动变成链接直接转到包裹查询网站等等。管道工的功能，就是让我们可以很方便的自定义这些转发功能，而不依赖于应用程序的实现。在 Plan 9 系统中，即使你不装 Skype, 不用 Gmail, 用户依然能够通过制定正则表达式匹配规则，来决定如何处理电话号码和包裹追踪号码等等。</p>
<p>管道工的原作者用编译器和编辑器的例子来说明管道工的作用。我们知道编译器报错语法错的时候，会以一定格式报出发生错误的文件和行号，如</p>
<blockquote><p>Line 43: Hello.cc syntax error.</p></blockquote>
<p>我们可以设定规则，在用户点击这些错误信息的时候，让管道工自动匹配和提取文件名，行号，并自动发给编辑器，就省却了我们人工打开编辑器跳到某行这个繁琐的步骤。尽管 IDE 已经通过集成编辑器和编译器的方式绕开了这种进程间通信，这种匹配/转发的通信方式仍然用在不少地方。比如 Vim 就引入了一个叫 errorformat (错误格式)的机制，让编辑器能够理解和匹配“错误格式”，并跳到指定的行。</p>
<p>通过 Plan 9 from user space 这个开源实现，我们可以在 Mac 和 Linux 上使用管道工。不过我们已经有了很多现成的工具能够部分实现管道工的功能。因为我日常只用浏览器和shell，因此简略介绍一下我是如何在浏览器和shell中实现类似于管道工的功能的。</p>
<p>用油猴子或者其他浏览器插件，我们可以将网页中某特定的字符串转变成一个定制的链接。然后，取决于所在平台，我们可以将这些链接和预定义的应用程序挂钩。Mac 下一个好用的工具是 <a href="http://www.rubicode.com/Software/RCDefaultApp/">RCDefaultApp</a> ，Linux/Gnome 下的 gconftool-2　也直接支持对 URL-handler 的修改。Windows 下的方法则是修改注册表。（当然这些方法都有安全隐患，所以只适合个人使用）。</p>
<p>在终端里，对于 Linux 用户，urxvt 这个终端非常强大，可以使用 perl 扩展来匹配和执行命令，基本上可以完全实现管道工的这种匹配任意字符串且发送给其他程序的功能。在 Mac OS X 中，<a href="http://www.iterm2.com/#/section/home">iTerm 2</a> 是程序员应该用的终端。该终端目前还没有 urxvt 的强大扩展性，不过也能完成大部分匹配任务。比如说，iTerms 的最新版本支持一个叫做 Sementic History 的功能 (Preference -&gt; Profile -&gt; Advanced)。这个功能使得我们可以直接点击 Terminal 里面的文件名召唤出 Finder。用苹果的可能都知道 Mac 里有个 <a href="http://developer.apple.com/library/mac/#documentation/UserExperience/Conceptual/AppleHIGuidelines/Windows/Windows.html">Proxy Icon</a> （应用程序标题栏里面的小图标）的概念，我们可以直接把这个小图标当成文件的代表，拖来拖去，甚至可以直接拖到 Gmail 中当附件。我们其实可以把 iTerms 2 里面的文件名直接当成一个对象拖来拖去。</p>
<p>因为我日常只使用浏览器和终端，Plan 9 的管道工给我的启发是，如果有一套好的进程间通信机制，拷贝粘贴是完全没有必要的。如果你和我一样基本不用鼠标，并且认为拷贝粘贴是一个降低工作效率的事情，那么我建议你尝试一下用管道工的思想去改善你的工作流，看看哪些拷贝粘贴是可以由计算机完成的。</p>
<div id="google_plus_one"><g:plusone></g:plusone></div><img src="http://feeds.feedburner.com/~r/xumathena/~4/ZPjvGFCVYU4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.youxu.info/2011/11/24/plan-9-plumber/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>UNIX 痛恨者手册读后笔记</title>
		<link>http://blog.youxu.info/2011/10/14/notes-on-the-unix-haters-handbook/</link>
		<comments>http://blog.youxu.info/2011/10/14/notes-on-the-unix-haters-handbook/#comments</comments>
		<pubDate>Sat, 15 Oct 2011 04:23:01 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[reading]]></category>
		<category><![CDATA[tech]]></category>

		<guid isPermaLink="false">http://blog.youxu.info/?p=1223</guid>
		<description><![CDATA[UNIX 痛恨者手册[PDF]可以算是一本奇书了。一般的技术书，写作缘由大多是作者特别喜欢某样技术，兴高采烈地拿出来和读者分享。而此书的几个作者，都是因为恨 UNIX 恨到“人生长恨水长东”... ]]></description>
			<content:encoded><![CDATA[<div>UNIX 痛恨者手册[<a href="http://simson.net/ref/ugh.pdf">PDF</a>]可以算是一本奇书了。一般的技术书，写作缘由大多是作者特别喜欢某样技术，兴高采烈地拿出来和读者分享。而此书的几个作者，都是因为恨 UNIX 恨到“人生长恨水长东”的境界了，于是乎搞了个邮件组，广泛收集各种愤怒，最后基于邮件组里面张贴的各种抱怨，编撰成了痛恨者手册这样一本书，来专门宣泄对 UNIX 的愤怒，也算得上是空前绝后了。</p>
<p>尽管这本书视角独特，以现在的眼光看，作者的抱怨中，真正属于 UNIX 固有问题的只占 50%，其他如对 sendmail 排山倒海的批评，对 C＋＋ 的尽情嘲弄，实际上都不属于 UNIX 系统特有的。其他的 50%，则颇有历史意义，可以看到当年的 UNIX 系统是何其的“原始”。特别是对照现在的 Linux 来看，可以看出 Linux 作为当年 UNIX 的继承人，在文件系统，安全性，稳定性等等方面的巨大的进步。</p>
<p>除去一些对 UNIX 中具体 BUG 的批评，这本书的背后实际上是三种设计哲学间的交锋，我把这三种哲学叫做 MIT 哲学，UNIX 哲学和 GUI 系统哲学。“MIT 哲学”这个词，是借用那篇著名的 <a href="http://www.jwz.org/doc/worse-is-better.html">Worse is better</a> 文章中的叫法。MIT 哲学的代表是 LISP 机器，即提供一个 LISP 环境的机器。这个机器提供给用户的，是优雅的编程环境，如统一的内存管理，统一的函数式接口，良好的文档等等，一切程序员所需要的，都给准备好了。但这个系统不管是作为个人计算机还是作为工作站都没有获得成功。</p>
<p>GUI 系统哲学从施乐的 Alto 开始，到90年代中期 Windows 95 出现之前，已经颇有气象，特别是在个人计算机领域，几乎所有的个人计算机厂商都在提供自己的图形界面操作系统。GUI 系统的哲学，是友好的用户界面和一致的使用体验。至于具体的功能，则委托给具体的应用程序实现。</p>
<p>而 UNIX 哲学，则像是一种开放式系统的哲学：除去提供统一的系统调用和标准工具外(POSIX)，不强调系统的一致性。UNIX 像是一堆松散的积木堆起来的一个系统，在遵守 POSIX 标准的前提下（其实是个非常松散的标准）各个厂商都可以自己选择积木搭建系统。</p>
<p>UNIX 这种开放的，允许自由搭积木的做法，是和信奉MIT哲学的人水火不容的。这些用户在 UNIX 的因为开放造成的不一致性上尽情吐槽。比如说，UNIX 一个饱受诟病的缺憾是其命令行参数不统一。在命令行下，有的命令加 -h 是显示帮助，有的却是显示隐藏文件，还有的命令压根不接受 -h 参数。这样的问题，反映了 UNIX 在演化过程中缺少一个统一的规划。这在演化路径单一的其他操作系统上是不可想象的。再比如，UNIX 的计算模型很简单，即用 C 语言和 shell 对系统调用做一个胶水包装，不提供内存管理也不提供异常处理，文件系统也很低级，不支持文件恢复也不支持文件的元信息存储。而 MIT 的LISP 机器的计算模型和存储系统看上去都更加高级，统一的函数式接口，自动内存管理等等。用过 LISP 机器的人自然不习惯 UNIX 这种看上去“低级”的操作系统。结果是，用过 LISP Machine 的用户除了抱怨 UNIX 外，只能寻求在 UNIX 上构建一个新的层，来弥补 UNIX 的不足。这事情的一个结果就是造就了Emacs 这个怪兽，到最后几乎所有能在 UNIX 里做的事情，都能在 Emacs 里完成。这样，除了操作系统内核外，Emacs 完全取代了 UNIX 环境。Emacs 功能强大到大家都同意 Emacs 是个万能软件，而 vi 用户则开玩笑说 Emacs 是个缺少一个好编辑器的操作系统。大家都知道，Emacs 的作者正是从 MIT 出来的 Richard Stallman。</p>
<p>痛恨者手册的作者也是在 MIT 的 AI 实验室工作多年的技术人员。为了解释 UNIX 的成功，他借用了 Worse is better 中的说法（Garbriel 断言 C 语言和 UNIX 是终极计算机病毒），把 UNIX 归类为世界上第一个计算机病毒。书中提到，UNIX 和病毒的共同特征为：体积小，可传染多种宿主（可移植），变异快速等等。书中说， UNIX 的普及并不是因为它在技术比其他操作系统更加优越，只是因为可移植，可传染和变异快，才占据了很大一块用户份额。</p>
<p>这个解释我认为是相当精当的。相对于其他操作系统，UNIX 基于C书写，可移植和早期的免费分发方式，即使技术上不够好，仍然像流行性感冒一样蔓延。一传十，十传百，快速攻城略地。当时 UNIX 的风行程度可以从几个侧面来证明。八十年代初雨后春笋一般地冒出了很多新的UNIX公司，SUN 和 SGI 就是是借着 UNIX 成长起来的典型例子。他们短短几年间就靠 UNIX 工作站业务跑上了纳斯达克。微软和苹果是靠个人电脑业务起家的，各自都有自己的操作系统，却也跑到UNIX世界下注，都曾经推出过自家的UNIX发行版（分别叫做 <a href="http://en.wikipedia.org/wiki/Xenix">Xenix</a> 和 <a href="http://en.wikipedia.org/wiki/A/UX">A/UX</a>)。UNIX这个”病毒”在工作站和服务器上的寄生能力极强，直到后来演化能力和传播能力更强的“病毒” Linux 的出现，加上 .COM 泡沫破裂的一场大洗牌，才把 UNIX 的市场份额压了下去。Linux 则彻底继承了所有的“病毒”特性，除去原有的体积小，可移植外，通过开放内核源代码，造就了现在从超级计算机服务器到嵌入式系统无处不在的现状。从设备总量来说，世界上从未有一个操作系统如 Linux 如此成功。</p>
<p>可惜的是 MIT 哲学派本身没有成功的操作系统产品用来作为比较（除了Emacs这个运行在UNIX上的程序外），因此在批评 UNIX 上火力就欠缺了一分。为了写出一本厚厚的痛恨者手册砸向UNIX，就需要来自另外一派，即信奉GUI哲学的用户的愤怒。</p>
<p>这些用户的愤怒，主要集中在易用性上。图形界面操作系统的出现，本质上就是为了解决计算机的可用性问题。在图形界面系统出现之前，掌握计算机的使用需要的是阅读厚厚的手册。图形界面出现后，只需要几分钟的演示，普通用户即可操作计算机完成一些简单的任务。这种效率的本质提升，正是施乐的 Alto 和苹果的 Macintosh 的革命性所在。而 UNIX 所拥有的，是一堆两个字母的命令，不一致的命令行参数，和一个实际上不是为 GUI 系统设计的 X 图形系统。命令难记，X 又臃肿，即使有了这些仍然没有构成一个统一的桌面系统（所以后来才有KDE 和  Gnome)，也难怪用户吐槽不已了。</p>
<p>在这类来自 GUI 用户的抱怨中，出乎我意料的一条是对UNIX管道的抱怨。主要的批评点在于管道作为一种 IPC 机制本身不够强大，包括管道不支持双向数据流（双向管道的用例也极少)，只能把数据作为字节流而不能传递结构化数据，和指针等等。从传统 UNIX 用户的眼光来看，这些指责是很不公平的。管道的作用是串接程序的输入输出，将小工具串成强大的工具链。但管道并不是 UNIX 上唯一的 IPC 机制，UNIX 有其他的 IPC 机制来支持管道之外的功能。换一个角度看，要求管道支持双向通信，结构化通信等等，正是从 GUI 哲学出发的对管道的批判。在 GUI 世界，进程间的通信有了两种新的方式：1、把小程序全部集成到一个大的多线程窗口程序中来进行线程间通信； 2、通过在不同程序间复制粘贴对象。从这两个角度考虑，自然会要求 UNIX 管道能像线程间通信一样双向，以及支持有结构的对象而不是单纯的字节流。</p>
<p>GUI 程序的这一套新的进程间通信机制，改变了所在平台的软件架构。UNIX 的软件架构，是围绕软件工具(Software Tools) 的概念展开的，归结起来就是每个工具做一件事情，且做到最好的哲学。因为 GUI 程序本身的复杂性，把林林总总的功能，放入一个大程序中让各模块直接在一个进程空间里互相通信成了一个通行的做法。比如电子表格软件中的公式计算，无需代理到 bc 这样的外部计算器中，直接由内置的模块完成。在这种哲学的指导下，为了给提供全面的解决方案，各种商业程序都追求大而全，内置各种可能用到的功能，因此体积也越来越大。几百兆大小的商业软件不足为奇了。UNIX 痛恨者手册推崇这种只能算局部最优的程序构建方法，而反过来抱怨管道这个另一个局部最优不够好，在我看来是有历史局限性的。</p>
<p>总的来说，这本书代表了 UNIX哲学以外的其他两种哲学对 UNIX 尖锐的批评，是值得当成UNIX 发展史的一部分而一读的。</p>
</div>
<div id="google_plus_one"><g:plusone></g:plusone></div><img src="http://feeds.feedburner.com/~r/xumathena/~4/-aLl_TobNpM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.youxu.info/2011/10/14/notes-on-the-unix-haters-handbook/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>编程珠玑番外篇 -K. 高级语言是怎么来的-7</title>
		<link>http://blog.youxu.info/2011/09/27/lisp-prehistory/</link>
		<comments>http://blog.youxu.info/2011/09/27/lisp-prehistory/#comments</comments>
		<pubDate>Tue, 27 Sep 2011 21:49:28 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[CompSci]]></category>
		<category><![CDATA[pearl]]></category>

		<guid isPermaLink="false">http://blog.youxu.info/?p=1213</guid>
		<description><![CDATA[LISP 语言前传 Lisp 的主要设计者 John McCarthy 曾经就 Lisp 的发展史，专门写过一篇 History of Lisp 的文章。这里介绍的历史，基本史实部分参照了 John McCarthy 的这篇文章，以及同时期 MIT 的关于 Lisp ... ]]></description>
			<content:encoded><![CDATA[<div>
<h2 id="internal-source-marker_0.7188789076171815" dir="ltr">LISP 语言前传</h2>
<p>Lisp 的主要设计者 John McCarthy 曾经就 Lisp 的发展史，专门写过一篇 <a href="http://www-formal.stanford.edu/jmc/history/lisp/lisp.html">History of Lisp</a> 的文章。这里介绍的历史，基本史实部分参照了 John McCarthy 的这篇文章，以及同时期 MIT 的关于 Lisp 的技术报告。</p>
<p>Lisp 的历史要从 IBM 的神奇机器 704 说起。此时是 1954 年，尽管距离 1946 年第一台计算机 ENIAC 的出现已经八年了，商用计算机市场还仅仅起步。很早就进入计算机市场的 IBM 做出了一个影响深远的决定：发布一台可以进行浮点计算的，面向科学和工程的电子计算机。这台计算机，很朴素地跟着 IBM 之前发布的 701，702 后，被编号成 704（不知为什么 IBM 从来没公布过 703）。说 704 是神奇机器，是因为这台机器在计算机科学发展史上意义重大：世界上最早的语音合成程序就是由 Bell 实验室的科学家在 IBM 704 上完成的。 Fortran，Lisp 也是最早在 IBM 704 上实现的。</p>
<p>和当年的所有计算机一样，IBM 704 是个百万美元级别的大玩具，不是一般人甚至一般大学能够买得起的。好在 IBM 和大学的关系一向很紧密，在 1957 年的时候，决定捐一台 704 给 MIT。当时在 Dartmouth 教书的 John McCarthy 和在 MIT 教书的 Marvin Minsky 关系很好，因此这台即将到达的 704，即将成为 McCarthy 的新玩具。</p>
<p>当年部署一台计算机的周期很长，为了不让自己闲着，McCarthy 决定一边等机器部署，一边研究一下如果有了这台机器，可以做点什么。当时 Minsky 手里有一个 IBM 的项目，内容是使用计算机证明平面几何问题。既然计算机没来不能写程序，他们就只能从抽象的层面思考问题的解决方法。这个思考的结果，是开发一套支持符号计算的 Fortran 子系统。他们的基本想法是，用一系列的 FORTRAN 子程序，来做逻辑推理和符号演绎。</p>
<p>回头看，这条路的确绕开了没有 704 就写不了程序的路障。因为我们只需要大致了解 Fortran 能够做什么，不能做什么，无需实际 Fortran 编程，就可以假想我们已经有了一系列未来可以实现的子程序，然后只要在数学上证明这些通过子程序的组合，加上自动逻辑推理，就可以证明平面几何定理。这就把一个计算机工程学问题，抽象成了一个数学问题（日后这个领域被正式划归到人工智能的学科中，但在当时这还是属于数学问题）</p>
<p>这样，计算机没来之前，McCarthy 的最终结果，是一个用 Fortran 子程序做列表处理的简单系统。McCarthy 的这条路很现实的做法——如果不用 Fortran 而是自己写一个新的语言的编译器话，可能需要好几年的时间。而 McCarthy 当年还不是终身教授，投入到写作新语言这样旷日持久且不能保证成果的项目中去，不会对他的职业生涯有太大的正面作用。</p>
<p>704 送到 MIT 后， McCarthy 带着两个研究生，将之前计划的 Fortran 列表处理子程序实现了，并命名为 Fortran 列表处理语言 (FLPL) 。然而，因为 Fortran 语言本身的限制，McCarthy 对 FLPL 并不满意。他在写作自动求函数导数的程序时[a]，发现 FLPL 的弱点集中体现在两个地方。</p>
<p>第一个问题是递归。我们在 Fortran 语言怎么来的这一节已经提到，704 上的 Fortran 语言是不支持递归的。而 McCarthy 心中所设想的语言，很重要的一条就是递归：没有递归，很多列表处理的函数只能用循环来实现，而循环本身并不是 McCarthy 设想的语言的一部分。熟悉函数求导的链式法则的读者可以想像，没有递归的求导程序是何其难写，因为函数求导过程本身就是递归定义的。</p>
<p>第二个问题是 Fortran 的 IF 语句。IF 家族的分支语句，在计算机程序设计中可以说必不可少。在 McCarthy 那里 IF 就更重要了，因为几乎所有有递归函数的地方就有 IF（因为递归函数需要 IF 判断结束条件）。相信读者都很熟悉这种 IF 结构</p>
<pre style="padding-left: 30px;" dir="ltr">IF 条件 THEN</pre>
<pre style="padding-left: 30px;" dir="ltr">    一些语句;</pre>
<pre style="padding-left: 30px;" dir="ltr">ELSE</pre>
<pre style="padding-left: 30px;" dir="ltr">    另一些语句;</pre>
<pre style="padding-left: 30px;" dir="ltr">END IF</pre>
<p>这是从 ALGOL 语言一脉相承下来的，很“自然”的 IF 写法。而早期的 FORTRAN 的 IF 写法却不这么直观，而是</p>
<pre style="padding-left: 30px;" dir="ltr">IF (表达式) A B C</pre>
<p>取决于表达式的值是小于零，等于零还是大于零，分别跳到（等价于 goto）标签 A， 标签B 或者标签 C。这个 IF 隐含了三个 Goto，可以说和结构化编程的实践截然相反，降低了程序的可读性。 Fortran 首创的这个三分支跳转的 IF 饱受诟病，Fortran 77 开始支持结构化的 IF，而 Fortran 90 标准进一步宣布三分支跳转的用法已经“过时”，不支持使用。</p>
<p>在 McCarthy 那里，Fortran 的三分支跳转 IF 也不方便。为此，在 FLPL 中，他试图用一个叫 XIF 子程序完成类似于 IF 的分支功能，用法是：</p>
<pre style="padding-left: 30px;" dir="ltr">XIF(条件, 表达式A, 表达式B)</pre>
<p>取决于条件的满足与否，XIF 返回表达式A 或者表达式B 的值。很快，他发现，用子程序的方法实现 XIF，在语义上并不正确。我们知道，在 Fortran 和其他高级语言中，函数参数的值在进入函数之前必须全部确定。在 XIF 这里，不难看出，不管条件满足与否，我们都先要计算表达式A 和表达式B 的值。而 IF 是个分支逻辑，从语义上来说，应该只计算满足条件的分支的值。因此，用函数来实现 IF 是不正确的 [b]。</p>
</div>
<p style="padding-left: 30px;"><span style="color: #003366;">作为一个旁注，尽管 John McCarthy 早在50多年前就发现了函数实现 IF 是语义错误的，现代的程序员还常常犯这个错误。一个值得一题的例子是 C++ 逻辑运算符重载和短路表达式的不等价性。我们都知道，在 C 语言中，逻辑与 (&amp;&amp;) 和逻辑或( || ) 都隶属于短路表达式，也就是说，对于 A &amp;&amp; B 这样的表达式，如果 A 已经确定为 false，就无需计算表达式 B 的值，即 B 的计算被”短路”。以 C 为蓝本的 C++ 一方便保留了这些短路表达式，另一方面在面向对象的特性中，引入了运算符重载。具体来说，只要一个对象定义了 operator&amp;&amp; 成员函数，就可以进行 &amp;&amp; 运算。乍一看，这是一个很酷的特性，可以让程序员用 A&amp;&amp;B 这样的数学表达式表达复杂的逻辑关系。然而，仔细想想，  A.operator&amp;&amp;(B) 在语义上并不等价于 C 所定义的 A&amp;&amp;B，原因在于 A.operator&amp;&amp;() 是个函数，在求值之前需要先计算 B 的值，而后者是个短路表达式，本质上相当于 </span></p>
<pre style="padding-left: 30px;" dir="ltr"><span style="color: #003366;">IF A:</span></pre>
<pre style="padding-left: 30px;" dir="ltr"><span style="color: #003366;"> return True</span></pre>
<pre style="padding-left: 30px;" dir="ltr"><span style="color: #003366;">ELSE:</span></pre>
<pre style="padding-left: 30px;" dir="ltr"><span style="color: #003366;"> return B</span></pre>
<pre style="padding-left: 30px;" dir="ltr"><span style="color: #003366; font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-size: 13px; line-height: 19px; white-space: normal;">因为短路表达式不一定会对 B 求值，这两者从语义上就是不等价的。如果 B 不是一个简单的对象，而是一个复杂表达式的时候，对 B 求值可能有副作用，而这个副作用，是写 A &amp;&amp; B 并把它当做短路表达式的程序员所没有预见的。按照 C++ Gotcha 的说法，这很容易造成潜在的程序 Bug。实际上，C++逻辑运算符重载是一个危险的特性，很多公司的编程标准都禁止使用逻辑运算符重载。</span></pre>
<p>递归和 IF 两个问题，使得 Fortran 从本质上就不符合 McCarthy 期望，以 Fortran 为宿主的开发列表处理语言也不可能达到 McCarthy 想要的结果。因此，唯一的解，就是抛开 Fortran，从头开始，设计一个新的语言。值得注意的是，此时 McCarthy 正好跳槽到了 MIT 做助理教授，MIT 有足够多的编程强人，可以帮 McCarthy 完成这个编写新语言的任务。这个强人，就是 Steve Russell；这个语言，就是 Lisp。</p>
<p>[a] 读过 SICP 的读者会发现这是一道习题<br />
[b] 读过 SICP 的读者会发现这又是一道习题</p>
<p>&nbsp;</p>
<div id="google_plus_one"><g:plusone></g:plusone></div><img src="http://feeds.feedburner.com/~r/xumathena/~4/LD0GmtKAFcw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.youxu.info/2011/09/27/lisp-prehistory/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>童子军军规和习惯培养</title>
		<link>http://blog.youxu.info/2011/08/07/boy-scout-trainings/</link>
		<comments>http://blog.youxu.info/2011/08/07/boy-scout-trainings/#comments</comments>
		<pubDate>Mon, 08 Aug 2011 01:54:10 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[Culture]]></category>
		<category><![CDATA[USA]]></category>

		<guid isPermaLink="false">http://blog.youxu.info/?p=1200</guid>
		<description><![CDATA[我最喜欢的饼干是美国的女童子军饼干。这种饼干由女童子军协会统一制作，然后交给每个童子军支部售卖。参与童子军训练的小女孩通过售卖饼干，学会设定目标，制定计划，协调分配，管... ]]></description>
			<content:encoded><![CDATA[<p>我最喜欢的饼干是美国的<a href="http://www.girlscouts.org/program/gs_cookies/">女童子军饼干</a>。这种饼干由<a href="http://www.girlscouts.org/">女童子军协会</a>统一制作，然后交给每个童子军支部售卖。参与童子军训练的小女孩通过售卖饼干，学会设定目标，制定计划，协调分配，管理财务，以及领导团队。每年春天，在美国生活的人都会在大大小小的超市门口，看到一群女孩子卖饼干。这些训练，是读书完全不能企及的。男童子军（与女童子军是独立的两个组织）的训练也很有特色，还记得 <a href="http://adisney.go.com/disneyvideos/animatedfilms/up/">Up</a> 里面的那个胖嘟嘟的小男孩么？他就是男童子军的一员，为了拿到一枚“野外探险”的徽章，居然误打误撞到南美转了一圈。要是想成为<a href="http://en.wikipedia.org/wiki/Eagle_Scout_(Boy_Scouts_of_America)">鹰徽童子军</a>（男童子军最高级别），需要<a href="http://www.scouting.org/scoutsource/BoyScouts/AdvancementandAwards/eagle.aspx">一系列的徽章</a>，难度基本上和在 Foursquare 上拿全所有徽章差不多。</p>
<p>男女童子军训练是很多国家儿童素质训练的重要一环。人的性格和习惯到了成年实习就比较难改变了。未成年时期的如童子军训练这样的项目，是培养一个“人”的很好的方式。人生中的最重要的好习惯，往往是在幼年少年时期，甚至在幼儿园学到的。实际上，对好习惯进行有意识的培养是社会教育应有的部分。因为这些好习惯不光可以塑造一个“人”，也能够让所在的社会更加美好。这些好习惯可以推广到生活和工作的很多方面。比如程序员们很熟悉的 Bob Martin 大叔，就围绕这一条男童子军的“整洁”的“军规”，<a href="http://www.informit.com/articles/article.aspx?p=1235624&amp;seqNum=6">硬生生写了本叫做 &lt;Clean Code&gt;</a>。这条军规的背后，是童子军创始人 Baden-Powell 留给男童子军的最后的话，当你离开一个世界的时候，试着让这个世界比你发现他的时候更加好 (Try and leave this world a little better than you found it)。这句话的指导意义，既用在定义人生上，也可以用在整理房间上，或者对公共场所垃圾的处理上。当然，也可以像 Martin 大叔一样用在代码重构上。</p>
<p>因为内人是女童子军成员，最近准备搬家整理东西的时候，整理出了一大捆女童子军训练的材料，其中一本叫做“6-9年级女童子军手册”的书，我不经意瞄了一眼，觉得有些话写得真好，特别是女童军的“成功生活”的八个原则，因此简单的翻译一下。</p>
<p>女童子军的“成功生活”的八个训练：</p>
<p>1. 管理你的时间 (Managing Your Time)<br />
2. 正确处理压力 (Handling Stress)<br />
3. 学会表达自己 (Speaking up for yourself)<br />
4. 时刻保持安全 (Stay safe)<br />
5. 获取管理钱财 (Earning and managing money)<br />
6. 注意合理消费 (Becoming a responsible consumer)<br />
7. 准备满意职业 (Preparing for satisfying career)<br />
8. 做负责任抉择 (Making responsible decision)</p>
<p>这八条原则如果孤立开来看，就和市面上大部分成功学书一样，并无特别之处。不过，考虑到这是未成年时期的训练，效果和成年之后再主动反向训练，难度是有区别的。现代认知心理学的一个基本假设是，人可以通过提高自己的认知能力（心智），改变自己的思维方式，对事情的看法，控制（相对难以控制的）感情，以及获得精神上的愉悦和在现实中的成功等等。少年时期的这些训练，正是对人认知能力的一种系统性的提升。成年之后用认知心理学方法反过来训练大脑和行为习惯，固然目标明确，却有事倍功半之感。</p>
<p>我觉得我小时候很幸运，有意无意的受到了多方面好习惯的训练。相信很多读者都受过类似的好习惯的训练，不过像童子军这样分门别类为这些好习惯设置配套训练项目还是第一次见到。如果将来我有小孩子，一定送他/她参加这样的童子军训练。诸位读者中有不少家长，想必也很注意对小孩的好习惯的培养，或许参阅美国的童子军训练的一些项目会有一些新的启发。</p>
<div id="google_plus_one"><g:plusone></g:plusone></div><img src="http://feeds.feedburner.com/~r/xumathena/~4/64dhKDG8S_o" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.youxu.info/2011/08/07/boy-scout-trainings/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>技术文章的质量</title>
		<link>http://blog.youxu.info/2011/06/26/technical-blog-postings/</link>
		<comments>http://blog.youxu.info/2011/06/26/technical-blog-postings/#comments</comments>
		<pubDate>Sun, 26 Jun 2011 23:29:33 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[Life]]></category>

		<guid isPermaLink="false">http://blog.youxu.info/?p=1191</guid>
		<description><![CDATA[推友 @StarrySource 就微薄和推特的好坏问题写了一篇文章，正好和霍炬的文章同时发出来，推特上对这两篇文章叫好的人不少，其中还有一些直接就说 StarrySource 这篇比 virushuo 写得好。文章好坏... ]]></description>
			<content:encoded><![CDATA[<p><!-- p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px 'Heiti SC Light'} p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px} span.s1 {font: 12.0px Helvetica} -->推友 <a href="http://twitter.com/StarrySource">@StarrySource</a> 就微薄和推特的好坏问题写了<a href="http://5li.de/wb/">一篇文章</a>，正好和<a href="http://blog.devep.net/virushuo/2011/06/26/microblogging.html">霍炬的文章</a>同时发出来，推特上对这两篇文章叫好的人不少，其中还有一些直接就说 StarrySource 这篇比 <a href="http://twitter.com/virushuo/">virushuo</a> 写得好。文章好坏诚然是个很主观的事情，不过就仅从文章内容来说，就算有一千个读者一千个主观标准，我也想不出什么理由来说明 StarrySource 的这篇比 virushuo 写得好，因为客观上这两篇文章的差距会抵充掉主观上的一些好恶。</p>
<p>在 StarrySource 的文章中，推特的开放性是一个事实判断，但是不是因为推特刚开始太小所以才做 API 的就很难说了。要知道，推特做 API 的时候，正是 flicker 和 delicious 靠 API 赢得了大量用户的时候。我们很难反向的说当年做 API 不做客户端是人手不够，我们也没见到人手够的 flickr 做看图传图的客户端，即使是在被 Yahoo! 收购之后。小公司以开放式 API 起家的奇迹，推特是非常特别的一个。现在推特开始做客户端什么的也的确是一个事实判断，但是多大程度会影响它的开放平台就很难预测了。它提供一条龙的服务，不意味着初期的开放策略受到了影响，而仅仅是推特开始挤占一些上下游而已。</p>
<p>新浪出手做微薄的时候，也邯郸学步做了 API。StarrySource 文在这里试图通过对比推特和新浪的策略不同，来说明新浪的用户体验很好。新浪有图床有富媒体呈现是事实，遗憾的是新浪在所谓的开放式 API 上，<del>也和当年没图床的推特一样，做出了一套不支持上传图片的 API</del>，对富媒体的支持却和 Web 界面不相匹配，这就特别奇怪了。更加奇怪的是， GEO （用户地理位置）在微薄上根本就不是一个显著的特性，因为微薄用户不比推特这样，大部分是移动设备用户，况且中国的地理定位的基础设施几乎没有，但新浪偏偏和推特一样，有 GEO 部分的 API。要知道推特是靠 GEO 赚了钱的，所以这就奇怪到家了。 从这个例子不难看出，虽然事实是新浪做的东西是推特的超集，实际上还是跟在推特后面试图复制推特的特性，并加入自己擅长的特性。这里微薄从来就没有过一以贯之的想着“要提高用户体验”。我想整个新浪产品线都不是从提高用户体验出发设计的，这一点只要用户新浪产品的用户都体会到。</p>
<p>至于在产品设计这节的观点，和菜头和@virushuo 已经说的够多的了，无需多话。在用户这节作者对言论审查，言论，小圈子等等的阐述，只会让经历过推特的人觉得不值一驳罢了。虽然我不知道 StarrySource 推友的背景，但仅从这篇文章的内容看，抽取掉事实之后，得到的是几个零散的观点，不构成论证的观点；相比之下，霍炬这篇有完整的论据，论证，甚至还包括了不少从论证引出的可证伪的论断。我想，不能因为主观上喜欢新浪微薄，就说霍炬的文章写得烂吧。</p>
<p>推特上推友开玩笑说这文章好像可能吧的文风。可能吧的文风是什么样子的呢，我有体会。首先，文章有充足的事实和引用，就差直接引用原文了。其次，文章不管内容多少，总要组织成一小节一小节的，用写书的结构写一篇2000字的博客文章，这样给人的印象是思维清晰。然后，排版是所有的中文博客里不是最好就是第二好的。一篇技术评论，有了上面这三样，再有一些不太离谱的观点和文字填充一下，基本上就可以算是一篇在中文圈子里相对好的文章了。受众反正也极少看英文的东西，所以我想可能吧访问量还不错。我和可能吧没什么过节，以上就是说说而已。对于我个人来说，我不订阅那些一个月写三篇以上的“干货”博客，因为我不相信这些内容的质量。好文章需要有深度思考和长期观察，而很不幸，这两样是稀缺资源。一个月的阅读和思考的结果，说不定也就够写一篇文章。</p>
<div id="google_plus_one"><g:plusone></g:plusone></div><img src="http://feeds.feedburner.com/~r/xumathena/~4/rPL7cbXp-qU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.youxu.info/2011/06/26/technical-blog-postings/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>编程珠玑番外篇-K. Plan 9 的故事（修订版）</title>
		<link>http://blog.youxu.info/2011/03/21/story-of-plan-9-revised/</link>
		<comments>http://blog.youxu.info/2011/03/21/story-of-plan-9-revised/#comments</comments>
		<pubDate>Mon, 21 Mar 2011 18:12:42 +0000</pubDate>
		<dc:creator>Eric</dc:creator>
				<category><![CDATA[pearl]]></category>

		<guid isPermaLink="false">http://blog.youxu.info/?p=1188</guid>
		<description><![CDATA[（本文是对于之前编程珠玑番外篇系列中 Plan 9 的八卦这一篇的彻底修订，本文得到了博文视点的卢鸫翔编辑的很多帮助） 计算机发展史上，创新性产品层出不穷。其中，有些想法和产品在技... ]]></description>
			<content:encoded><![CDATA[<div><em>（本文是对于之前编程珠玑番外篇系列中 <a href="http://blog.youxu.info/2008/10/06/about-plan/">Plan 9 的八卦</a>这一篇的彻底修订，本文得到了博文视点的卢鸫翔编辑的很多帮助）</em></div>
<div></div>
<div>计算机发展史上，创新性产品层出不穷。其中，有些想法和产品在技术上很先进，却很遗憾的没有获得广泛的接纳和商业的成功。不过，只要时机到来，这些创新，往往都会以新的面目再次复兴。</p>
<p>这样的例子在历史中屡见不鲜。Jobs 和 Apple 分手后开创的 NeXT 公司的操作系统和硬件设备，创新点很多，市场反响却不大。而 NeXT 系统在软件和硬件设计上的创新，以及工业设计的思想，最终成为了现在 iOS 系统、Mac 系统软硬件设计的基石。同样是 Apple, 当年出品的 Hypercard 软件，首创了超文本格式和交互式页面。虽然 HyperCard 的这些创新在当时并不显得太出众，最终被苹果终止开发。但到了 Internet 出现之后，Tim Berners-Lee 受到这种“超文本 (hypertext)”格式的启发，将这些思想平移到联网的计算机上，由此出现了万维网。Ward Cunningham 更是受这一张一张的“数字卡片”受到，发展出了世界上第一个 wiki 系统 WikiWikiWeb。所有的这些例子，都说明了一项当时未必得到大多数人认可的创新可能会在意想不到的地方凤凰重生。 本节我们介绍的 Plan 9 操作系统，也是这样的一个例子。</p></div>
<div>
<h3>FTPFS 虚拟文件系统</h3>
<p>大部分读者应该都用过 FTP 在两台机器之间传送文件。FTP 是一种简单成熟的传输协议。试想现在我们需要修改一个 FTP 服务器上的文件，我们无法直接用本机上的编辑器打开这个远程的文件编辑，而需要先下载这个文件，修改后再上传。这种编辑远程文件的方法显然比编辑本机的文件麻烦多了。 我们退后一步仔细想一下这个不方便，会发现，文件是同样的一个文件，只是因为文件不在本地，我们需要借助于 FTP 协议访问，所以我们就不能直接编辑它了（事实上有些功能强大的编辑器如 VIM 仍然可以编辑，但普通的编辑器则不能）。在一切都是文件的假设下，我们可以不加区别的访问软盘，硬盘和闪存盘上的文件，但这里，因为中间多了一个网络协议，这种“一切都是文件”的方便特性就消失了。 因为这个需求很常见，很多 FTP 客户端，如 Windows 下的 LeapFTP, Mac 下的 Cyberduck，都做了一个贴心的功能，在你想要编辑远程文件的时候，自动将其下载成一个临时文件，等你修改结束后又自动上传。但是这依赖于 FTP 客户端，并不是每个客户端都提供了这类支持。</p>
<p>FTPFS 就是针对上面提出的这种不方便而出现的一种技术。通过利用一个叫做 FUSE (Filesystem in Userspace) 的技术，FTPFS 允许用户将远程的 FTP 文件系统挂载到本地的文件系统上，使得用户可以像操作本地文件一样操作远程文件1，包括查看，编辑，删除和重命名等等。而实际网络传输协议的细节，则对用户隐藏了。实际上，FUSE 技术可以用来实现很多“虚拟”的文件系统，而不仅限于将 FTP 文件系统挂载到本地文件系统上这一种。比如，使用 HTTP 协议的文件系统，SSH 服务器上的文件，Flicker 上的图片，维基百科上的文章，都可以通过 FUSE，抽象成一种虚拟的挂载在本地文件系统上的文件系统。这些虚拟的文件系统，隐藏了协议的细节，将各种不同类型的协议支持下的资源抽象成一个文件系统，也可以挂载到本地的文件系统上。</p>
<p>虚拟文件系统能把资源无差别的抽象成文件系统。这种做法消除了网络协议的不同造成的访问障碍，方便了用户对各种不同资源的访问。这种 “消除协议差异，一切资源都是文件”的思想，实际上来源于 Plan 9。毫不令人惊讶的是，在 Plan 9 中，干脆就没有 FTP 这个命令，所有对 FTP 的操作都是采用挂载 ftpfs 挂载文件系统的方式实现的。</p>
<p><strong>一切都是文件（这次是真的）</strong></p>
<p>上面我们提到了虚拟文件系统可以把资源无差别地抽象成一个文件系统，而这个思想是来源于 Plan 9 操作系统的。且慢，早在 UNIX Programming Environment 中， Brian W. Kernighan 就提出了 “UNIX 中，一切都是文件” 的设计哲学。事实上，UNIX 中的确很多对象是文件：进程是文件，设备是文件，命名管道也是文件。但是，也有很多不是文件，尤其是由其他非 Bell 实验室加入 UNIX 的组件。举例来说，计算机网络设备和服务不是文件（UNIX 的网络支持部分最先由 UC Berkerly 开发），图形界面中的对象也不是文件（UNIX 的图形界面支持最初由 MIT 的 X 工作组开发）。“一切都是文件” 这个口号因为 UNIX 的发展和新模块的加入而不再贴切。</p>
<p>UNIX 出现的时候，支持的设备都很简单，都可以抽象成文件交由内核统一管理，由内核提供 read/write 等系统调用访问设备。随着硬件的发展，一些新的硬件需要有超越系统调用范围的控制方式（例如我们可以控制光盘驱动器弹出托盘，而这个操作在传统磁盘驱动器上是不存在，也不能简单的抽象为 read/write 甚至 unmount 操作），或者为效率着想，需要用户空间程序直接和设备通信（如网卡，高速硬盘）。因为这些需求，和为未来扩展性考虑，Bell 实验室在 UNIX 第七版中，也不得不引入 ioctl 等具有无穷扩展性的系统调用机制，配合设备驱动程序，支持对设备的控制。这些做法，绕开了原先统一的 read/write 设备访问方式。也就是说，设备再也不能简单地抽象为文件了。</p>
<p>随着 UNIX 发展而失却的“一切都是文件”的纯粹哲学，正是 Plan 9 想要恢复的。在 Plan 9 中，通过实现一个叫做 9P 的文件协议，用户可以自由的把任何资源或服务抽象成本地的一个“虚拟的”文件或者目录，而对这些文件的操作，会通过 9P 协议，自动映射到对原来资源或者服务的操作。 这样，访问资源的各种细节就被隐藏了。在对付那些需要 ioctl 或者其他控制机制的设备或者应用程序时，Plan 9 提倡将程序的控制部分抽象成一个支持 read/write 的 ctl 文件，而非使用专门的 ioctl 系统调用。这样，其他程序就可以通过读写 ctl 文件与被控制的程序通信。从对资源和对控制的抽象不难看出来，Plan 9 把 UNIX 中“一切都是文件”的思想做了进一步的升华。在 Plan 9 里面，真的是一切都是文件了──设备是文件，窗口管理器是文件，Email 程序是文件（实际上所有程序都是文件），网络是文件（实际上所有服务包括 DNS 都是文件），等等。</p>
<h3>Plan 9 的创新</h3>
<p>要说 Plan 9 的特性，就不能不先介绍一下它的几个创造者。和 UNIX 一样， Plan 9也是从 Bell 实验室计算机科学研究中心开发的。其项目主要负责人是 Rob Pike （现在在 Google 工作，负责 Go 编程语言），当时在 Bell 实验室的很多人，包括 UNIX 的两位创始人，Ken Thompson 和 Dennis Ritchie ，以及 Brain Kernighan、Doug Mcllroy （UNIX 管道的提出者）都参与了这个项目的开发。从某种意义上来说，Plan 9 有点充当 UNIX 继承人的味道。事实上 Rob Pike 最初，也的确是想构建一个更加“现代的 UNIX”。除了坚持 UNIX 中已经成功了的“一切都是文件”，“KISS”等原则外，Plan 9 在原有 UNIX 的设计理念上做了新突破，其中最值得一提的，就是“分布式操作系统” 的理念。</p>
<p>Plan 9 这个分布式操作系统的出现和当时计算机发展的趋势是密不可分的。我们都知道， UNIX 是一种分时操作系统，用户分享机器资源。UNIX 操作系统则负责在各任务（或者说进程）之间调度。因此，UNIX 是一个中心化的操作系统。CPU、内存、IO 以及所有的任务的调度都是集中被 UNIX 管理的。上世纪 80 年代中期，更加便宜的微型计算机开始普及。这些微型计算机各自有着磁盘、CPU、内存和 IO 设备。Plan 9 的指导思想，就是把微机组织起来，方便的实现资源共享。</p>
<p>Plan 9 里，能共享的资源包括文件系统、图形界面、IO 设备、以及 CPU 和内存等计算资源。这些资源之间千差万别，我们固然可以针对每种资源设计一个协议，如文件分享用 NFS，图形界面用 X 协议，打印机用 CUPS 协议等等，不过这种做法在 Plan 9 的设计者看来是不够优雅的。他们采用的，是在上文我们已经提到过的“一切都是文件”的方法[cite:Plan 9, a distributed system]。我们可以用两个很有启发性的例子来说明。</p>
<p>例一、替换 CPU</p>
<p>假想一下我们有一台日常使用但性能不佳的笔记本，和一台不在本地但性能强劲的服务器。 我们当然能够使用远程计算机的强劲的 CPU 运行一些计算量特大的程序。这不是什么难事，因为几乎所有操作系统都支持登陆到远程的机器。然而，麻烦的是，如果在远程运行程序需要读写本地的文件，或者访问挂载在本地笔记本上的打印机，扬声器麦克风之类设备，我们除了在本地和远程之间把文件传来传去之外，并没有什么好方法。特别的，如果我们想借用另一台计算机上强劲的 CPU 做音频和视频解码，来播放一个放在本机光盘驱动器里的电影文件的话，我们是不可能指望远程计算机既能读本地的光驱，又能把音频投递到本机的扬声器上的。</p>
<p>Plan 9 中，有一个简单的 cpu 命令，能够让用户自然地使用一个其他机器上的 CPU 运行程序，且仍然能够访问本地的所有文件和设备。也就是说，我们可以用远程计算机上强劲的 CPU 做图像处理，媒体解码等任务，并且可以直接把声音播放到本地的扬声器。cpu 命令给人的感觉，是除了给机器换个了 cpu 外，其他一切都和原来一样。这个看似 “神奇” 的功能，其实在 Plan 9 里实现起来一点都不复杂： cpu 指令首先连接服务器上，然后将本地的所有资源和文件系统，包括窗口管理器，光盘驱动器，扬声器等设备（别忘了他们都是文件），一股脑儿挂载到服务器上，成为服务器上的资源。这样，在服务器上运行的程序，就可以“自然地”使用本地的键盘鼠标和显示器完成交互，还可以访问你本地的显示器扬声器等设备。</p>
<p>cpu 命令真的就是名副其实的换掉了本地计算机的 cpu （其实还有内存）而保留其他一切设备。Plan 9 的这个 cpu 命令，带有强烈的分布式操作系统的特征，而我们平时接触的操作系统都不是分布式操作系统，因此 cpu 这个命令至今在现代主流操作系统上没有完全等价物。</p>
<p>例二、进程间控制和通信</p>
<p>进程间通信可以提高使用计算机的效率（详细请参见 Page XX：开发人员为何应该使用 Mac OS X）。UNIX 下的管道就是一个经典的进程间通信的例子。在图形界面程序和集成化的程序出现后， 应用程序不断的把多种功能集成到一起，进程间通信反而变得相对困难了。比如说，即使有个给汉字加拼音的程序，除了来回复制粘贴，我们还是不能方便地从文字编辑程序中选取一段自动加上拼音。而 UNIX 下的编辑器可以借助管道很简单完成这样的操作。这个问题的本质困难，用操作系统的眼光来看，在于进程这个对象，没有在运行时暴露出应有的通信和控制接口。</p>
<p>Plan 9 的一切都是文件的思想从一个新的角度，解决了程序间的数据共享问题。Plan 9 倡导应用程序在运行时都把自己的内部状态抽象成一个文件系统。举例来说，一个邮件客户端程序不光支持图形界面下查看邮件，用户还能够直接通过</p>
<p>cat /mail/fs/inbox/1/subject<br />
cat /mail/fs/inbox/1/body</p>
<p>来查看收件箱（inbox）中第一封邮件的主题和内容。这种设计，使得应用程序不再成为进程间通信的障碍，从而拷贝粘贴也变得没有必要。比如说，我们可以直接把草稿箱里邮件的内容通过管道送给其他拼写检查器。邮件客户端提供的拼写检查器再差也没关系了。这种把应用程序中的对象暴露出来的想法，和 Mac OS X 中的应用程序暴露一个Applescript 字典的设计思想异曲同工。</p>
<p>同样的道理，Plan 9 也从一切都是文件的思想出发，解决了了程序控制问题。 Plan 9 鼓励每个应用程序和设备在抽象成文件的时候，都暴露出一个抽象的 ctl 文件。这样，其他应用程序可以通过向 ctl 文件写命令的方式，运行时控制应用程序。举例来说，Plan 9 的窗口管理器 Rio，提供了 ctl 文件，我们可以通过读取和写入 ctl 文件，实现一些 Rio 本身不支持的如平铺所有窗口的操作。同样，通过对邮件程序的 ctl 操作，我们可以实现邮件的发送和接受的控制等等。Mac OS X 下的 Applescript 也可以完成类似的功能。遗憾的是，除了 Plan 9 和 Mac OS X，其他操作系统对这类进程间控制和通信的支持都不够完整。</p>
<h3>实践者指南</h3>
</div>
<div>上面介绍的 Plan 9 特性，可以说仅仅是冰山一角 Plan 9 里还有很多其他创新，如 Rio 窗口管理器简化了窗口管理，fossil 文件系统使增量备份毫不费力，/proc 文件系统方便对系统的控制和支持远程 debug 等等。我们可以在桌面通信的 DBus 标准，Mac OS X 的 Time Machine, Linux 的 /proc 文件系统里找到这些技术的影子。因为 Plan 9 从来就没有大众化，有不少创新不为外人所知。</p>
<p>对 Plan 9 感兴趣，想要更多了解 Plan 9 的读者，可以到 http://plan9.bell-labs.com/plan9/ 下载 Live CD， 并在多台联网的机器或虚拟机中安装该系统。喜欢 Plan 9 里的一些命令，而不想折腾系统的读者，可以到 http://swtch.com/plan9port/ 下载可以在 Linux，Mac OS X 等主流操作系统上运行的 Plan 9 的移植程序。Rob Pike 的网站 cat-v.org 有最完整的 Plan 9 的资料，以及对 UNIX 设计哲学的反思。</p></div>
<div></div>
<div>Plan 9 中的很多思想，如/proc sysfs，还有 userspace 的虚拟文件系统，对 IPC 的重新处理如 DBus ，轻量级别的窗口管理器，UTF-8 等等，实际上都融入了 Linux 等现代操作系统。对于 Plan 9 这样含有众多优秀设计思想的操作系统，为什么最终没有流行开来，自然是很多人关心的。 ESR 曾经说，可能是因为当时 UNIX 已经足够好了。这样的解释很容易让人想起那句著名的 Worse is better。具体是什么原因呢，就交给各位读者思考了。</div>
<div></div>
<div id="google_plus_one"><g:plusone></g:plusone></div><img src="http://feeds.feedburner.com/~r/xumathena/~4/CWEhClxPzXA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.youxu.info/2011/03/21/story-of-plan-9-revised/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
	</channel>
</rss><!-- Dynamic page generated in 1.334 seconds. --><!-- Cached page generated by WP-Super-Cache on 2013-04-02 02:01:09 --><!-- Compression = gzip -->
