avatar
a*i
1
说话间就到了晌正时分,商成便请几位王爷在家里吃顿便饭。
说是便饭,其实并不随便。商成才到京时,家里就请过大师傅,但手艺实在不好意
思拿出来待客;先后换了两拨,可置办的酒馔总是差强人意。直到月儿她们来到以后,
二丫请大商号永盛昌的东家袁澜出面,从袁家经营的太白楼里聘了三位做宴席的大师傅
,“应县伯府席面难吃”的笑话才渐渐消停下来。但商成在京城里没什么故旧,早前在
燕山认识的一些朋友又都是每天从早到晚公务忙不完的人,难得聚上一回;再加他到京
伊始便招惹了一大堆的宰相和上柱国,手里又没握着实权,别人就是再想求上进也不可
能跑来烧他的冷灶,所以家里很难得才会待一回客。请回家的三位大师傅,本来还想着
要好好地在新东家露个脸,可到了县伯府,每天除了指点着别人做完简简单单的三顿饭
,居然就再没有伸胳膊露脸的机会。钱拿得多,事做得少,这人的心头就总是觉得不踏
实。今天好不容易碰见几位王爷一起过府作访,不用主家吩咐,个个打起十二分精神拿
出看家的手艺,精心置备了一大桌的菜馔,摆得满条案琳琅满目,就预备着听一声赞叹
博一声喝彩。
可惜的是,不管是商成还是几位王爷,大家的心思都没在这顿茶饭上。
现在还是太子的服丧期间,自己还在受着禁足的处分,所以商成也没让人摆出一人
一案的燕饮席,大家按着长幼高低的顺序,凑合着聚在一张大方桌边。也不搞什么三巡
酒五巡酒的规矩。只有第一圈是他这个主人把着酒壶挨个斟上大家同饮,然后就是各人
随意。
汝阳王大约是喝不得酒,小半盏的霍氏青花陈酿下去,脸色便有些发红,话也渐渐
多起来。吃了一会酒,混七搭八地和旁边人说了一会话,他夹了一筷子盐拌葱段在嘴里
嘎吱嘎吱嚼着,忽然就隔着桌问商成道:“子达,我听说你和张伯淳很有罅隙的,眼看
着他就要倒了,你怎么突然跳出来帮他了?”
桌边一下就安静起来,清河郡王、江陵王、襄州王还有那两个嗣王,都停下话,一
起拿眼睛望着商成。
商成和张朴有矛盾,这事知道的人不少。几位王爷虽然遵循祖宗立下的规矩不经务
实事,也不怎么和朝廷的文武官员往来,可毕竟都是宗室领袖,个个手眼通天,对这个
事情自然也是有所耳闻。但也仅仅是耳闻而已。本来嘛,他们是宗室,张朴和商成是朝
廷大员,你走你的阳关道,我过我的独木桥,八杆子下去也不可能把两边打到一起,张
朴与商成如何,关碍着他们什么事呢?可眼下再不关心却是不行!
别看人们一提到宗室二字,除了尊敬就是敬仰,可谁知道宗室的酸甜苦辣?在宗室
这个光鲜的门脸背后,又是一付什么样的情景?
宗室也苦啊!太祖立下的规矩,宗室不能执掌权柄,因此“权”这条路陈氏子弟是
别想了,京官能做到六部的郎中,外官做到上州的知府,就基本上到头了,再想向前一
步,开国以后还没有先例。太宗时又立下一个“福传三世”的规矩,哪怕是亲王封爵,
也只能传三代,亲王传一子为嗣王,传一孙为郡王,然后封爵就要被收回。亲王的其他
的子孙,除了在家谱上能留个名之外,基本上得不到多少实际的好处。少数人运气好,
还能得到一个恩荫,而其他的陈家子孙,想做官需要自己去参加科举,想发财需要自己
懂得经营,就算想种几亩地糊口,也需要先有几亩土地;总之一句话,三代以外的宗室
,基本上什么都要靠自己,哪怕是巴结奉承别人,那也要靠自己脸皮厚、眼光准和嘴皮
子利索。立国百余年来,现在宗室里录册的子弟已经有两万多人,这其中只有少数人身
上还有爵位或者官职,其他的人都和普通百姓一样,要缴纳夏秋两季赋税,要操心一家
的吃喝穿用,要为生计而奔波……但他们毕竟都是陈家的子弟,哪怕家徒四壁到了吃上
顿没下顿的烂糟地步,可向上数几代,他们和清河郡王、汝阳王还有天子一样,都是同
一个老祖宗一一大家同出一门,凭什么你们可以喝酒吃肉,我们却只能吞糠咽菜?所以
从高宗年间开始,去爵的陈家子弟便开始闹腾。随着时光的流逝,去爵的人越来越多,
也就越闹越厉害。前几年过大年礼祭的时候,还有日子过不下去的人拖家带口地趴在宗
祠里哭,当场让代天子祭祖的成都王下不来台。东元帝拿着这些人也没办法,再怎么说
这也是亲戚,既不能打也不能骂,只好自己掏荷包从内帑里拿些出来给他们。不能不说
,这是个非常糟糕的解决办法;从那以后,每年的春秋大祭,都有人去祖祠里闹腾,东
元帝也只能一次又一次地掏钱。到了现在,但凡是氏族里有点什么重要的事,就必然会
有人跳出来哭闹一回,而“陈氏哭祠”,更是成了一个笑柄……
陈家子弟做的这种荒唐事,不仅让天子落颜面,也让清河郡王他们这些宗室领袖挠
头发愁一一这丢人的是陈氏一族啊!但他们也没什么好办法。钱,他们是有一些,可要
想一气周济两万的子弟,那简直就是在做梦!两万子弟都是拖家带口的,连家室带儿女
一起算,那可是几万口,他们那些钱撒下去,能翻起点浪花就算不错。何况他们也有家
室和儿女,也是一大家子的人,他们同样需要为子孙做打算。尤其是象清河郡王这样的
,本身就是最后一代封爵,几个儿子十几个孙子都没有爵位和俸禄,就更需要为他们今
后做盘算。这些年,清河郡王豁出去老脸不要了,撒泼打滚地求人,好不容易才给两个
儿子和五个孙子张罗了几个官职。可就为了这个事情,他便再没有了安生时候。没得到
差事的儿孙都说他偏心,儿孙媳妇里更是说什么难听话的都有,家里一天到晚地吵得鸡
犬不宁,他根本就弹压不住。有时候家里闹腾得太厉害,他甚至想到,自己怎么还不闭
眼呢?自己要是能早点伸腿就好了,至少可以图个清净。
现在好了,天上掉下一块大馅饼,商燕山鼓捣出一个东倭方略,捎带着他还弄出一
个东倭借债的事。关键是这个借债,这才是大好事!就算不能象就算东倭没有金山银山
,只要借债的事能办下来,凭着分五的月息,一年掏几回荷包的天子可以舒一口气了,
他们这些人的担心也有个指望了,而宗室里有胆色有出息的子弟,也可以去东倭找条好
出路一一东倭各地的港口、税司、矿山……到处都需要人手。况且这借给东倭的债可不
是一年两年里就能还上的,说不定就是数十年上百年。分五的月息,利翻利利滚利,六
百万缗的帐债到了最后,那得是多少?还有开山采矿、冶炼金银、贩运铜铁……其中的
利钱实在太大了,大到教人不敢深想,更不敢细算!
但有一个问题,大家却不能不想:东倭方略,朝廷占了大便宜;宗室放债给前三口
,大家可以得到数不尽的红利;谷实纠集宗室一起来放债,谷家就可以在宗室的帮助下
度过眼前的难关;而前三口有了这笔钱,他就可以在大赵的支持下坐上倭王的位置。那
么,提出建议的商燕山,他能得到什么,或者说,大家能帮他什么忙?更高的爵位他是
别想了,更高的勋衔更不要去指望,官职他差不多做到了头,钱财他好象也不是很缺一
一剩下的就只能是权柄了。但他上头还压着萧坚和杨度,这两个人不下去,他就别想出
头;这一点大家心里清楚,他心里肯定也有数。除了这些,他还能有什么希图?未必真
的如汝阳王所说,他想把张朴搞下去?但这说不通道理呀。张朴倒了,他一个武将能有
什么好处?
商成一口饮尽盏里的残酒,笑了一下,无可奈何地说道:“有罅隙也没办法。总不
能眼睁睁地看着机会就这样白白地溜过去吧?”
汝阳王张了张嘴,到底还是没说话。清河郡王却不在乎。商成与张朴不和,他和张
朴更是对头,前月朱宣主持的那个《对核土地田亩告事》刚刚布告天下,他就断言“今
时朱仲宽之种祸,他日必贻害四方”;其实这话后面还有一句,“大赵之乱,自张伯淳
始!”这话说得实在太重了,又很有几分谶语的意味,因此没有人敢四处传扬,许多人
都不知道。他直截说道:“子达,你可以缓上一段时间再提嘛。等张朴卷起铺盖卷滚蛋
了,你再上奏朝廷,这样,不仅事情依旧能办成,还能让新上去的宰相记下你的人情。”
商成摇了摇头,苦笑着说:“就是没时间啊。每年的五六七三个月,去东倭最方便
。尤其是六月底七月初,是东南季风和东南洋流最强的时候,这个时候下海去东倭,走
南方航线只需要七到十天就能在东倭的本州岛登陆,不出意外的话,十五天之内就能解
决藤原氏,从而实现东倭方略的第一步。假如错过这段时间,因为风向和洋流的缘故,
就只能走北方航线,从明州出发,经登州到高丽,再由高丽到东倭,这条路,光是海上
就要行走一个月一一这还是一切顺利的情况下。要是高丽那边的联系稍微跟不上而错过
风信,就只能等到明年。”他停下了话,把几位王爷挨个望过去,最后又转过头看着清
河郡王,慢慢说道,“谁知道明年是个什么光景?”
没有人说话。
“只有抓住眼下,才是最关紧的。”商成继续说道,“眼下北边突竭茨人忙着舔伤
口,南边萧老将军还没朝南诏动手,京城里又安静,恰好是个四方没事也没人跳出来生
事的时候,打东倭正是其时。况且,宰相公廨正在为清查田亩隐户的事情而焦头烂额,
巴不得有点事情发生,以便转移人们的视线,所以肯定会大力地支持。”
众人想着其中的道理,都是点头同意。谷实说:“我看,宰相公廨也是没办法了。
就算是没有东倭的事,他们也干不长久,所以即便东倭这一仗打输了,他们也就是请辞
的结果而已,最多也就是提早几个月。可要是赢了呢?要是在东倭找到了金山银山呢?”
“那张伯淳这右相就必然会改任左相了。”汝阳王笑着说道,“有了东倭的胜仗,
再有了金山银山,要是萧坚再在西南好好胜上一两仗,那他张伯淳就是咱们大赵的名相
了。他青史留名,咱们大家发财,皆大欢喜嘛。”又惋惜地对商成说,“只有子达,你
是没什么好处的。功劳都是别人的,财也是大家的……要不,咱们大家给子达留上一大
股?”
清河郡王首先表态:“这事没什么可说道的!还有谷鄱阳。他奔波劳碌一回,也要
分一大股。”
大家都点头同意。当然,所有的股金里最大的一股肯定是东元帝的;这一点大家心
头都很清楚。只是现下还没来得及把事情告诉天子,也不知道天子最后能拿出多少钱,
所以也就没人提具体会分给商成和谷实各自多少的分额一一肯定不能比天子更多就是了
。不管东元帝最后会拿出多少钱,总之,谁的股都不能比天子多。
商成笑着拒绝了大家的好意。理由是他没钱。他的钱一部分投在航海技术开发上,
还有一大笔预备要送去应县的封国,那边要花钱的地方更多。
不管商成是真没钱还是假没钱,几位宗室都笑着接受了他的解释。宗室不能揽权,
又不能带头破坏朝廷制度去兼并土地,爵位还不能子子孙孙地继承下去,为了子孙的福
祉,只能在经营上想办法,因此他们比寻常人更加地看重一个“利”字。商成让出一大
股,宗室里当然就可以有更多的股可以分配,这当然是求之不得的好事。他们也因此而
更加地感激他。
清河郡王心头畅快,忍不住就多喝了些酒,说话也就愈加地没有顾忌。他首先称赞
了商成,感谢他替宗室解决了一个棘手的大问题,随后就开始大骂张朴和朱宣不是东西
。他确信张朴就是个奸相,而朱宣这个书蠹就是张朴的帮凶!
这个话题立刻引起了大家的共鸣。在座的全是大地主,对《对核土地田亩告事》都
是恨之入骨,于是纷纷指责这是一个祸国殃民的文告……
avatar
t*n
2
听用一代MBA的人反映,有过热导致系统变慢的问题。
不知道late 2010 MBA这个问题解决了没。
我正考虑入手一台13'MBA w/4G memory
avatar
p*u
3
总是有人喜欢争论这类问题,到底是“函数式编程”(FP)好,还是“面向对象编程”
(OOP)好。既然现在出了两个帮派,就有人积极地做它们的帮众,互相唾骂和残杀。
然后呢,又出了一个“好好先生帮”,这个帮的人喜欢说,管它什么范式呢,能解决问
题的工具就是好工具!
我个人其实不属于这三帮人中的任何一个。
面向对象编程(Object-Oriented Programming)
如果你看透了表面现象就会发现,其实“面向对象编程”本身没有引入很多新东西。所
谓“面向对象语言”,其实就是经典的“过程式语言”(比如Pascal),加上一点点抽
象能力。所谓“类”和“对象”,基本是过程式语言里面的记录(record,或者叫结构
,structure),它的本质就是一个从名字到数据的“映射表”(map)。你可以用名字
从这个表里面提取相应的数据。比如point.x,就是用名字'x'从记录point里面提取相
应的数据。这比起数组来是一件很方便的事情,因为你不需要记住存放数据的下标。即
使你插入了新的数据成员,仍然可以用原来的名字来访问已有的数据,而不用担心下标
错位的问题。
所谓“对象思想”(区别于“面向对象”),实际上就是对这种数据访问方式的进一步
抽象。一个经典的例子就是平面点的数据结构。如果你把一个点存储为:
struct Point {
double x;
double y;
}
那么你用point.x和point.y可以直接访问它的X和Y坐标。但你也可以把它存储为极坐标
方式:
struct Point {
double r;
double angle;
}
那么你可以用point.r和point.angle访问它的模和角度。可是现在问题来了,如果你的
代码开头把Point定义为第一种XY的方式,使用point.x, point.y访问X和Y坐标,可是
后来你决定改变Point的存储方式,用极坐标,你却不想修改已有的含有point.x和
point.y的代码,怎么办呢?
这就是“对象思想”的价值,它让你通过更进一步的“间接”(indirection,或者叫
做“抽象”)来改变point.x和point.y的语义,从而让使用它们的代码完全不需要修改
。虽然你的实际数据结构里面根本没有x和y这两个成员,由于.x和.y可以被重新定义,
你可以通过改变.x和.y的含义来模拟它们。在你使用point.x和point.y的时候,系统内
部其实在运行两片代码,它们的作用是从r和angle计算出x和y的值。这样你的代码就感
觉好像x和y是实际存在的成员一样,而其实它们是被临时算出来的。在Python之类的语
言里面,你可以通过定义“property”来直接改变point.x和point.y的语义。在Java里
稍微麻烦一些,你需要使用point.getX()和point.getY()这样的写法。然而它们最后的
目的其实都是一样的——它们为数据访问提供了一层“间接”(抽象)。
这种抽象是非常好的想法,它甚至可以跟量子力学的所谓“不可观测性”扯上关系。你
觉得这个原子里面有10个电子?也许它们只是像point.x给你的幻觉一样,也许宇宙里
根本就没有电子这种东西,也许你每次看到所谓的电子,它都是临时生成出来逗你玩的
呢?然而,这就是对象思想的一切。你见过的所谓“面向对象思想”,几乎无一例外可
以从这个想法推广出来。面向对象语言的绝大部分特性,其实是过程式语言早就提供的
。因此我觉得,其实没有语言可以叫做“面向对象语言”。就像一个人为一个公司贡献
了一点点代码,并不足以让公司以他的名字命名一样!
“对象思想”,作为数据访问的抽象,是有一定好处的。然而“面向对象”(多了“面
向”两个字),就是把这种本来良好的思想东拉西扯,牵强附会,发挥过了头。很多面
向对象语言号称“所有东西都是对象”(Everything is an Object),把所有的函数
都放进所谓对象里面,叫做“方法”(method),把普通的函数叫做“静态方法”(
static method)。实际上呢,就像我之前的例子,只有极少需要抽象的时候,需要使
用内嵌于对象之内,跟数据紧密结合的“方法”。其他的时候,你其实只是想表达数据
之间的变换操作,这些完全可以用普通的函数表达,而且这样做更加简单和直接。这种
把所有函数放进方法的做法是本末倒置的,因为函数其实并不属于对象。绝大部分函数
是独立于对象的,它们不能被叫做“方法”。强制把所有函数放进它们本来不属于的对
象里面,把它们全都作为“方法”,导致了面向对象代码逻辑过度复杂。很简单的想法
,非得绕好多道弯子才能表达清楚。很多时候这就像把自己的头塞进屁股里面。
这就是为什么我喜欢开玩笑说,面向对象编程就像“地平说”(Flat Earth Theory)
。当然你可以说地球是一个平面,对于局部的,小规模的现象,它貌似没有问题。然而
对于通用的,大规模的情况,它却不是自然,简单和直接的。直到今天,你仍然可以无
止境的寻找证据,扭曲各种物理定律,自圆其说“地球是平的”这个幻觉,然而这会让
你的理论非常复杂,经常需要缝缝补补还难以理解。
面向对象语言不仅有自身的根本性错误,而且由于面向对象语言的设计者们常常是半路
出家,没有受到过严格的语言理论和设计训练却又自命不凡,所以经常搞出另外一些奇
葩的东西。比如JavaScript,每个函数同时又可以作为构造函数(constructor),所
以每个函数里面都隐含了一个this变量,你嵌套多层对象和函数的时候就发现没法访问
外层的this,非得bind一下。Python的变量定义和赋值不分,所以你需要访问全局变量
的时候得用global关键字,后来又发现如果要访问“中间层”的变量,没有办法了,所
以又加了个nonlocal关键字。Ruby先后出现过四种类似lambda的东西,每个都有自己的
怪癖…… 有些人问我为什么有些语言设计成那个样子,我只能说,很多语言设计者其
实根本不知道他们在干什么!
软件领域就是喜欢制造宗派。“面向对象”当年就是乘火打劫,扯着各种幌子,成为了
一种宗派,给很多人洗了脑。很多人至今不知道自己所用的“面向对象语言”里面的很
多优点,都是从过程式语言继承来的。每当发生函数式与面向对象式语言的口水战,都
会有面向对象的帮众拿出这些过程式语言早就有的优点来进行反驳:“你说面向对象不
好,看它能做这个……” 拿别人的优点撑起自己的门面,却看不到事物实质的优点,
这样的辩论纯粹是鸡同鸭讲,所以我懒得参加。
函数式编程(Functional Programming)
函数式语言一直以来比较低调,直到最近由于并发计算编程瓶颈的出现,以及Haskell
,Scala之类语言的流行,它忽然变成了一种宗派。有人盲目的相信函数式编程能够奇
迹般的解决并发计算的难题,而看不到实质存在的,独立于语言的问题。被函数式语言
洗脑的帮众,喜欢否定其它语言的一切,看低其它程序员。特别是有些初学编程的人,
俨然把函数式编程当成了一天瘦二十斤的减肥神药,以为自己从函数式语言入手,就可
以对经验超过他十年以上的老程序员说三道四,仿佛别人不用函数式语言就什么都不懂
一样。
各种“白象”(white elephant)
所谓白象,“white elephant”,是指价格昂贵,却没有实际用处的东西。函数式语言
里面有很多特殊的功能,它们跟白象的性质类似。
函数式语言的拥鳖们认为这个世界本来应该是“纯”(pure)的,不应该有任何“副作
用”。他们把一切的“赋值操作”看成低级弱智的作法。他们很在乎所谓尾递归,类型
推导,fold,currying,maybe type等等。他们以自己能写出使用这些特性的代码为豪。
可是殊不知,那些东西其实除了能自我安慰,制造高人一等的幻觉,并不一定能带来真
正优秀可靠的代码。大量使用fold和currying的代码,写起来貌似很酷,读起来却异常
痛苦。很多人根本不明白fold的本质,却老喜欢用它,因为他们觉得那是函数式编程的
“精华”,可以显示自己的聪明。然而他们没有看到的是,其实fold包含的,只不过是
在列表(list)上做递归的“通用模板”,这个模板需要你填进去三个参数,就可以生
成一个新的递归函数调用。所以每一个fold的调用,本质上都包含了一个在列表上的递
归函数定义。fold的问题在于,它定义了一个递归函数,却没有给它一个一目了然的名
字。使用fold的结果是,每次看到一个fold调用,你都需要重新读懂它的定义,琢磨它
到底是干什么的。而且fold调用只显示了递归模板需要的部分,而把递归的主体隐藏在
了fold本身的“框架”里。比起直接写出整个递归定义,这种遮遮掩掩的做法,其实是
更难理解的。比如,当你看到这句Haskell代码:
foldr (+) 0 [1,2,3]
你知道它是做什么的吗?也许你一秒钟之后就凭经验琢磨出,它是在对[1,2,3]里的数
字进行求和,本质上相当于sum [1,2,3]。虽然只花了一秒钟,可你仍然需要琢磨。如
果fold里面带有更复杂的函数,而不是+,那么你可能一分钟都琢磨不透。写起来倒没
有费很大力气,可为什么我每次读这段代码,都需要看到+和0这两个跟自己的意图毫无
关系的东西?万一有人不小心写错了,那里其实不是+和0怎么办?为什么我需要搞清楚
+, 0, [1,2,3]的相对位置以及它们的含义?这样的写法其实还不如老老实实写一个递
归函数,给它一个有意义名字(比如sum),这样以后看到这个名字被调用,比如sum [
1,2,3],你想都不用想就知道它要干什么。定义sum这样的名字虽然稍微增加了写代码
时的工作,却给读代码的时候带来了方便。为了写的时候简洁或者很酷而用fold,其实
增加了读代码时的脑力开销。要知道代码被读的次数,要比被写的次数多很多,所以使
用fold往往是得不偿失的。然而,被函数式编程洗脑的人,却看不到这一点。他们太在
乎显示给别人看,我也会用fold!
与fold类似的白象,还有currying,Hindley-Milner类型推导等特性。看似很酷,但等
你仔细推敲才发现,它们带来的麻烦,比它们解决的问题其实还要多。有些特性声称解
决的问题,其实根本就不存在。现在我把一些函数式语言的特性,以及它们包含的陷阱
简要列举一下:
fold。fold等“递归模板”,相当于把递归函数定义插入到调用的敌方,而不给它们名
字。这样导致每次读代码都需要理解几乎整个递归函数的定义。
currying。貌似很酷,可是被部分调用的参数只能从左到右,依次进行。如何安排参数
的顺序成了问题。大部分时候还不如直接制造一个新的lambda,在内部调用旧的函数,
这样可以任意的安排参数顺序。
Hindley-Milner类型推导。为了避免写参数和返回值的类型,结果给程序员写代码增加
了很多的限制。为了让类型推导引擎开心,导致了很多完全合法合理优雅的代码无法写
出来。其实还不如直接要程序员写出参数和返回值的类型,这工作量真的不多,而且可
以准确的帮助阅读者理解参数的范围。
代数数据类型(algebraic data type)。所谓“代数数据类型”,其实并不如普通的
类型系统(比如Java的)通用。很多代数数据类型系统具有所谓sum type,这种类型其
实带来过多的类型嵌套,不如通用的union type。盲目崇拜代数数据类型的人,往往是
因为盲目的相信“数学是优美的语言”。而其实事实是,数学是一种历史遗留的,毛病
很多的语言。
惰性求值(lazy evaluation)。貌似数学上很优雅,但其实有严重的逻辑漏洞。因为
bottom(死循环)成为了任何类型的一个元素,所以取每一个值,都可能导致死循环。
同时导致代码性能难以预测,因为求值太懒,所以可能临时抱佛脚做太多工作,而平时
浪费CPU的时间。由于到需要的时候才求值,所以在有多个处理器的时候无法有效地利
用它们的计算能力。
尾递归。大部分尾递归都相当于循环语句,然而却不像循环语句一样具有一目了然的意
图。你需要仔细看代码的各个分支的返回条件,判断是否有分支是尾递归,然后才能判
断这代码是个循环。而循环语句从关键字(for,while)就知道是一个循环。所以等价
于循环的尾递归,其实最好还是写成特殊的循环语句。当然,尾递归在另一些情况下是
有用的,这些情况不等价于循环。在这种情况下使用循环,经常需要复杂的break或者
continue条件,导致循环不易理解。所以循环和尾递归,其实都是有必要的。
纯函数
半壶水都喜欢响叮当。很多喜欢自吹为“函数式程序员”的人,往往并不真的理解函数
式语言的本质。他们一旦看到过程式语言的写法就嗤之以鼻。比如以下这个C函数:
int f(int x) {
int y = 0;
int z = 0;
y = 2 * x;
z = y + 1;
return z / 3;
}
很多函数式程序员可能看到那几个赋值操作就皱起眉头,然而他们看不到的是,这是一
个真正意义上的“纯函数”,它在本质上跟Haskell之类语言的函数是一样的,也许还
更加优雅一些。
盲目鄙视赋值操作的人,也不理解“数据流”的概念。其实不管是对局部变量赋值还是
把它们作为参数传递,其实本质上都像是把一个东西放进一个管道,或者把一个电信号
放在一根导线上,只不过这个管道或者导线,在不同的语言范式里放置的方向和样式有
一点不同而已!
对数据结构的忽视
函数式语言的帮众没有看清楚的另一个重要的,致命的东西,是数据结构的根本性和重
要性。数据结构的有些问题是“物理”和“本质”地存在的,不是换个语言或者换个风
格就可以奇迹般消失掉的。函数式语言的拥鳖们喜欢盲目的相信和使用列表(list),
而没有看清楚它的本质以及它所带来的时间复杂度。列表带来的问题,不仅仅是编程的
复杂性。不管你怎么聪明的使用它,很多性能问题是根本没法解决的,因为列表的拓扑
结构根本就不适合用来干有些事情!
从数据结构的角度看,Lisp所谓的list就是一个单向链表。你必须从上一个节点才能访
问下一个,而这每一次“间接寻址”,都是需要时间的。在这种数据结构下,很简单的
像length或者append之类函数,时间复杂度都是O(n)!为了绕过这数据结构的不足,所
谓的“Lisp风格”告诉你,不要反复append,因为那样复杂度是O(n2)。如果需要反复
把元素加到列表末尾,那么应该先反复cons,然后再reverse一下。很可惜的是,当你
同时有递归调用,就会发现cons+reverse的做法颠来倒去的,非常容易出错。有时候列
表是正的,有时候是反的,有时候一部分是反的…… 这种方式用一次还可以,多几层
递归之后,自己都把自己搞糊涂了。好不容易做对了,下次修改可能又会出错。然而就
是有人喜欢显示自己聪明,喜欢自虐,迎着这类人为制造的“困难”勇往直前 :)
富有讽刺意味的是,半壶水的Lisp程序员都喜欢用list,真正深邃的Lisp大师级人物,
却知道什么时候应该使用记录(结构)或者数组。在Indiana大学,我曾经上过一门
Scheme(一种现代Lisp方言)编译器的课程,授课的老师是R. Kent Dybvig,他是世界
上最先进的Scheme编译器Chez Scheme的作者。我们的课程编译器的数据结构(包括AST
)都是用list表示的。期末的时候,Kent对我们说:“你们的编译器已经可以生成跟我
的Chez Scheme媲美的代码,然而Chez Scheme不止生成高效的目标代码,它的编译速度
是你们的700倍以上。它可以在5秒钟之内编译它自己!” 然后他透露了一点Chez
Scheme速度之快的原因。其中一个原因,就是因为Chez Scheme的内部数据结构根本不
是list。在编译一开头的时候,Chez Scheme就已经把输入的代码转换成了数组一样的
,固定长度的结构。后来在工业界的经验教训也告诉了我,数组比起链表,确实在某些
时候有大幅度的性能提升。在什么时候该用链表,什么时候该用数组,是一门艺术。
副作用的根本价值
对数据结构的忽视,跟纯函数式语言盲目排斥副作用的“教义”有很大关系。过度的使
用副作用当然是有害的,然而副作用这种东西,其实是根本的,有用的。对于这一点,
我喜欢跟人这样讲:在计算机和电子线路最开头发明的时候,所有的线路都是“纯”的
,因为逻辑门和导线没有任何记忆数据的能力。后来有人发明了触发器(flip-flop)
,才有了所谓“副作用”。是副作用让我们可以存储中间数据,从而不需要把所有数据
都通过不同的导线传输到需要的地方。没有副作用的语言,就像一个没有无线电,没有
光的世界,所有的数据都必须通过实在的导线传递,这许多纷繁的电缆,必须被正确的
连接和组织,才能达到需要的效果。我们为什么喜欢WiFi,为什么喜欢4G网,这也就是
为什么一个语言不应该是“纯”的。
副作用也是某些重要的数据结构的重要组成元素。其中一个例子是哈希表。纯函数语言
的拥护者喜欢盲目的排斥哈希表的价值,说自己可以用纯的树结构来达到一样的效果。
然而事实却是,这些纯的数据结构是不可能达到有副作用的数据结构的性能的。所谓纯
函数数据结构,因为在每一次“修改”时都需要保留旧的结构,所以往往需要大量的拷
贝数据,然后依赖垃圾回收(GC)去消灭这些旧的数据。要知道,内存的分配和释放都
是需要时间和能量的。盲目的依赖GC,导致了纯函数数据结构内存分配和释放过于频繁
,无法达到有副作用数据结构的性能。要知道,副作用是电子线路和物理支持的高级功
能。盲目的相信和使用纯函数写法,其实是在浪费已有的物理支持的操作。
好好先生
很多人避免“函数式vs面向对象”的辩论,于是他们成为了“好好先生”。这种人没有
原则的认为,任何能够解决当前问题的工具就是好工具。也就是这种人,喜欢使用
shell script,喜欢折腾各种Unix工具,因为显然,它们能解决他“手头的问题”。
然而这种思潮是极其有害的,它的害处其实更胜于投靠函数式或者面向对象。没有原则
的好好先生们忙着“解决问题”,却不能清晰地看到这些问题为什么存在。他们所谓的
问题,往往是由于现有工具的设计失误。由于他们的“随和”,他们从来不去思考,如
何从根源上消灭这些问题。他们在一堆历史遗留的垃圾上缝缝补补,妄图使用设计恶劣
的工具建造可靠地软件系统。当然,这代价是非常大的。不但劳神费力,而且也许根本
不能解决问题。
所以每当有人让我谈谈“函数式vs面向对象”,我都避免说“各有各的好处”,因为那
样的话我会很容易被当成这种毫无原则的好好先生。
符号必须简单的对世界建模
从上面你已经看出,我既不是一个铁杆“函数式程序员”,也不是一个铁杆“面向对象
程序员”,我也不是一个爱说“各有各的好处”的好好先生。我是一个有原则的批判性
思维者。我不但看透了各种语言的本质,而且看透了它们之间的统一关系。我编程的时
候看到的不是表面的语言和程序,而是一个类似电路的东西。我看到数据的流动和交换
,我看到效率的瓶颈,而这些都是跟具体的语言和范式无关的。
在我的心目中其实只有一个概念,它叫做“编程”(programming),它不带有任何附
加的限定词(比如“函数式”或者“面向对象”)。我的老师Dan Friedman喜欢把自己
的领域称为“Programming Languages”,也是一样的原因。因为我们研究的内容,不
局限于某一个语言,也不局限于某一类语言,而是所有的语言。在我们的眼里,所有的
语言都不过是各个特性的组合。在我们的眼里,最近出现的所谓“新语言”,其实不大
可能再有什么真正意义上的创新。我们不喜欢说“发明一个程序语言”,不喜欢使用“
发明”这个词,因为不管你怎么设计一个语言,所有的特性几乎都早已存在于现有的语
言里面了。我更喜欢使用“设计”这个词,因为虽然一个语言没有任何新的特性,它却
有可能在细节上更加优雅。
编程最重要的事情,其实是让写出来的符号,能够简单地对实际或者想象出来的“世界
”进行建模。一个程序员最重要的能力,是直觉地看见符号和现实物体之间的对应关系
。不管看起来多么酷的语言或者范式,如果必须绕着弯子才能表达程序员心目中的模型
,那么它就不是一个很好的语言或者范式。有些东西本来就是有随时间变化的“状态”
的,如果你偏要用“纯函数式”语言去描述它,当然你就进入了那些monad之类的死胡
同。最后你不但没能高效的表达这种副作用,而且让代码变得比过程式语言还要难以理
解。如果你进入另一个极端,一定要用对象来表达本来很纯的数学函数,那么你一样会
把简单的问题搞复杂。Java的所谓design pattern,很多就是制造这种问题的,而没有
解决任何问题。
关于建模的另外一个问题是,你心里想的模型,并不一定是最好的,也不一定非得设计
成那个样子。有些人心里没有一个清晰简单的模型,觉得某些语言“好用”,就因为它
们能够对他那种扭曲纷繁的模型进行建模。所以你就跟这种人说不清楚,为什么这个语
言不好,因为显然这个语言对他是有用的!如何简化模型,已经超越了语言的范畴,在
这里我就不细讲了。
我设计Yin语言的宗旨,就是让人们可以用最简单,最直接的方式来对世界进行建模,
并且帮助他们优化和改进模型本身。
avatar
d*o
4
真你妈瞎写,金山银山往外推。。。圣人啊
avatar
x*s
5
没有散热问题,不跑cpu intensive的软件根本听不到风扇声音。
avatar
w*g
6
是王垠写的吗?看到了indiana和各种吹嘘。

【在 p*u 的大作中提到】
: 总是有人喜欢争论这类问题,到底是“函数式编程”(FP)好,还是“面向对象编程”
: (OOP)好。既然现在出了两个帮派,就有人积极地做它们的帮众,互相唾骂和残杀。
: 然后呢,又出了一个“好好先生帮”,这个帮的人喜欢说,管它什么范式呢,能解决问
: 题的工具就是好工具!
: 我个人其实不属于这三帮人中的任何一个。
: 面向对象编程(Object-Oriented Programming)
: 如果你看透了表面现象就会发现,其实“面向对象编程”本身没有引入很多新东西。所
: 谓“面向对象语言”,其实就是经典的“过程式语言”(比如Pascal),加上一点点抽
: 象能力。所谓“类”和“对象”,基本是过程式语言里面的记录(record,或者叫结构
: ,structure),它的本质就是一个从名字到数据的“映射表”(map)。你可以用名字

avatar
p*r
7
盐拌葱段就是能拿得出的好东西? 大婶写的时候是不是在天马横空、胡思乱想

【在 a********i 的大作中提到】
: 说话间就到了晌正时分,商成便请几位王爷在家里吃顿便饭。
: 说是便饭,其实并不随便。商成才到京时,家里就请过大师傅,但手艺实在不好意
: 思拿出来待客;先后换了两拨,可置办的酒馔总是差强人意。直到月儿她们来到以后,
: 二丫请大商号永盛昌的东家袁澜出面,从袁家经营的太白楼里聘了三位做宴席的大师傅
: ,“应县伯府席面难吃”的笑话才渐渐消停下来。但商成在京城里没什么故旧,早前在
: 燕山认识的一些朋友又都是每天从早到晚公务忙不完的人,难得聚上一回;再加他到京
: 伊始便招惹了一大堆的宰相和上柱国,手里又没握着实权,别人就是再想求上进也不可
: 能跑来烧他的冷灶,所以家里很难得才会待一回客。请回家的三位大师傅,本来还想着
: 要好好地在新东家露个脸,可到了县伯府,每天除了指点着别人做完简简单单的三顿饭
: ,居然就再没有伸胳膊露脸的机会。钱拿得多,事做得少,这人的心头就总是觉得不踏

avatar
s*8
8
13寸比较凉快,11寸很热。
avatar
l*n
9
写这么长不容易。可以转行当作家
avatar
y*i
10
是史实啊。17世纪,石见银山采掘的银矿量占全球银矿的1/3。16世纪,日本许多地区
都发现了金山或者银山,于是领主就将之国有化,成为财政的主要来源,如武田家有甲
州的黑川、中山两座金山,今川家有安倍梅的岛金山,北条家有伊豆的金山,上杉家有
佐渡的鹤子银山,等等。
九州鹿儿岛的菱刈矿山,如今是世界上屈指可数的金山。菱刈矿山的金矿石品位为平均
每吨40克,黄金评估的标准一般认为,如果品位达到平均每吨2克的话,金矿山就能盈
利。菱刈矿山自1985年开始采掘以来,年产金矿7至10吨,在至今为止的23年间,产金
量达到165吨,这一数字,是佐渡矿山和鸿之舞矿山的两倍以上,菱刈矿山已经成为日
本历史上最大的金山了。而现在的问题是其尚存的埋藏量还有多少。据估计,至少还能
开采出近150吨。除菱刈矿山的产量以外,日本有史以来的产金量在1000吨上下。

【在 d*****o 的大作中提到】
: 真你妈瞎写,金山银山往外推。。。圣人啊
avatar
b*7
11
每天都用adobe creative suite 5都没有任何风扇声音,唯独bootcamp win7下跑古剑
奇谭风扇会响。
avatar
N*K
12
瞎jb扯 世界是物体构成的 面向对象的分析思路在人脑力也有 例如视觉的目标跟踪与
识别

【在 p*u 的大作中提到】
: 总是有人喜欢争论这类问题,到底是“函数式编程”(FP)好,还是“面向对象编程”
: (OOP)好。既然现在出了两个帮派,就有人积极地做它们的帮众,互相唾骂和残杀。
: 然后呢,又出了一个“好好先生帮”,这个帮的人喜欢说,管它什么范式呢,能解决问
: 题的工具就是好工具!
: 我个人其实不属于这三帮人中的任何一个。
: 面向对象编程(Object-Oriented Programming)
: 如果你看透了表面现象就会发现,其实“面向对象编程”本身没有引入很多新东西。所
: 谓“面向对象语言”,其实就是经典的“过程式语言”(比如Pascal),加上一点点抽
: 象能力。所谓“类”和“对象”,基本是过程式语言里面的记录(record,或者叫结构
: ,structure),它的本质就是一个从名字到数据的“映射表”(map)。你可以用名字

avatar
D*o
13
人家是说往外推

【在 y***i 的大作中提到】
: 是史实啊。17世纪,石见银山采掘的银矿量占全球银矿的1/3。16世纪,日本许多地区
: 都发现了金山或者银山,于是领主就将之国有化,成为财政的主要来源,如武田家有甲
: 州的黑川、中山两座金山,今川家有安倍梅的岛金山,北条家有伊豆的金山,上杉家有
: 佐渡的鹤子银山,等等。
: 九州鹿儿岛的菱刈矿山,如今是世界上屈指可数的金山。菱刈矿山的金矿石品位为平均
: 每吨40克,黄金评估的标准一般认为,如果品位达到平均每吨2克的话,金矿山就能盈
: 利。菱刈矿山自1985年开始采掘以来,年产金矿7至10吨,在至今为止的23年间,产金
: 量达到165吨,这一数字,是佐渡矿山和鸿之舞矿山的两倍以上,菱刈矿山已经成为日
: 本历史上最大的金山了。而现在的问题是其尚存的埋藏量还有多少。据估计,至少还能
: 开采出近150吨。除菱刈矿山的产量以外,日本有史以来的产金量在1000吨上下。

avatar
T*s
14
除了上 Steam 玩游戏会有点热, 其它时间都没什么感觉, 至少在运行同样软件下,
比另一台 ThinkPad x300 凉多了
估计与配置不同有关系, 1.6 Ghz, 4Gb, 128 SSD

【在 s*******8 的大作中提到】
: 13寸比较凉快,11寸很热。
avatar
y*i
16
这样啊。这个是不合理。

【在 D***o 的大作中提到】
: 人家是说往外推
avatar
p*y
17
这儿说的都是13寸的吗?
avatar
j*x
18
典型的树靶子自己打
骗sb的垃圾文。。。
听说是隐王写的?。。。
也难怪啊。。。

【在 p*u 的大作中提到】
: 总是有人喜欢争论这类问题,到底是“函数式编程”(FP)好,还是“面向对象编程”
: (OOP)好。既然现在出了两个帮派,就有人积极地做它们的帮众,互相唾骂和残杀。
: 然后呢,又出了一个“好好先生帮”,这个帮的人喜欢说,管它什么范式呢,能解决问
: 题的工具就是好工具!
: 我个人其实不属于这三帮人中的任何一个。
: 面向对象编程(Object-Oriented Programming)
: 如果你看透了表面现象就会发现,其实“面向对象编程”本身没有引入很多新东西。所
: 谓“面向对象语言”,其实就是经典的“过程式语言”(比如Pascal),加上一点点抽
: 象能力。所谓“类”和“对象”,基本是过程式语言里面的记录(record,或者叫结构
: ,structure),它的本质就是一个从名字到数据的“映射表”(map)。你可以用名字

avatar
t*n
19
可以组织一个“长子东征”
赫赫

【在 a********i 的大作中提到】
: 说话间就到了晌正时分,商成便请几位王爷在家里吃顿便饭。
: 说是便饭,其实并不随便。商成才到京时,家里就请过大师傅,但手艺实在不好意
: 思拿出来待客;先后换了两拨,可置办的酒馔总是差强人意。直到月儿她们来到以后,
: 二丫请大商号永盛昌的东家袁澜出面,从袁家经营的太白楼里聘了三位做宴席的大师傅
: ,“应县伯府席面难吃”的笑话才渐渐消停下来。但商成在京城里没什么故旧,早前在
: 燕山认识的一些朋友又都是每天从早到晚公务忙不完的人,难得聚上一回;再加他到京
: 伊始便招惹了一大堆的宰相和上柱国,手里又没握着实权,别人就是再想求上进也不可
: 能跑来烧他的冷灶,所以家里很难得才会待一回客。请回家的三位大师傅,本来还想着
: 要好好地在新东家露个脸,可到了县伯府,每天除了指点着别人做完简简单单的三顿饭
: ,居然就再没有伸胳膊露脸的机会。钱拿得多,事做得少,这人的心头就总是觉得不踏

avatar
z*7
20
13'
so far so good. smooth, quiet, and cool
avatar
e*s
21
how about 11'
avatar
e*o
22
搭车问 最新的mbp 15会很热吗? 风扇声音大不大?
avatar
d*a
23
我用的是11寸,1.4GHz,4GB,128GB SSD。极少过热,很安静。
这一代的MBA,能耗控制做到了家。

【在 e*****s 的大作中提到】
: how about 11'
avatar
m*u
24
我的13的mba跑win7时,风扇经常会想。
avatar
q*x
25
windows 7如果看sohu等flash heavy的网站,风扇很快就最快转。 其他的都还好,就
是对flash不够友好, 我配置是2.13/4G/256G
avatar
t*n
26
O(∩_∩)O谢谢你们的回复!
看来MBA 13基本上不用win7和特别费CPU的程序就没问题了。
avatar
b*7
27
同配置同感

【在 q*x 的大作中提到】
: windows 7如果看sohu等flash heavy的网站,风扇很快就最快转。 其他的都还好,就
: 是对flash不够友好, 我配置是2.13/4G/256G

相关阅读
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。