怪怪 | Nothing, Everything

"有过一个发疯的时刻,有感觉的钢琴以为它是世界上仅有的一架钢琴,宇宙的全部和谐都发生在它身上." - 狄德罗
随笔 - 94, 文章 - 3, 评论 - 1884, 引用 - 42
数据加载中……

2008年5月12日

喧嚣

过去两到三个月,一些总结是有的, 但很难说有很大进步,这是不得不意识到的。

 

从状态上来说:


1. 基本放弃了自我管理。

 

2. 目标对我来说似乎也没有威慑力了,毫无紧迫感。

 

3. 不能说毫无意义, 但确实一点也不充实。

 

从技术上来说:

 

1. 除了少数想法算一些整理, 没有悟到更多东西。

 

2. 一些地方反而过于热衷于言语, 而放弃了本质。

 

比如关于面向对象和其它范式的语言; 最早我就明白Anders说的“对象说到底不也是语法糖吗?”、“delegate就是函数式的全部了”, 但是实际上在这方面的思考并没有新的进展, 也包括对泛型、模板、元编程的体会上,还差那么一点点。

 

而对于“语法糖”这个概念, 不要光停留在表面理解, 类似于面向对象的非本质性, 对我个人来说,已经无需再讨论。相反,delegate并没有把C#变成强大的函数式语言,恐怕在于类型系统的配合度还不够,所以delegate在C#中就很容易表现的像个语法糖。作为具体的议题,后者是一个还存在模糊的地方,而我缺乏深思。

 

关键在于, 哪些东西不是语法糖; 这个地方我没有好好的把握住。 抓住这一点, 在设计和实现时就不会被迷花了眼, 在语言的学习和设想上, 也能更加的击中要害。 再重复一遍,哪些东西不是语法糖?界限在哪里?

 

实际的产品开发,也要重新进入轨道。最近缺乏实践的带动, 而在此之前, 对Web框架的理解,对各种编程范式的理解, 从经验上来说,都是被实践带动的。所以重新回到根本,即便对于高一层次的研究, 也是必要的了。

posted @ 2008-07-23 06:17 怪怪 阅读(255) | 评论 (5)编辑

资料收集

基础资料:

 

用来增加背景知识的资料:

 Why Gnutella Can't Scale. No, Really. 

(待更新)

 

可能需要了解的资料:

 

非结构化:


“Mobile Agent based Method”,这个想法初步感觉有点爽,和我的想法有相似性,找点文章来看。

 

Cache Method”的当前样例中, 有啥有新意的细节可以挖掘没有?

 

结构化:

(待更新)

 

实用资料:

 (待更新,这部分恐怕比较难找,可能还是得看代码。)

 

初步的想法, 实际上P2P网络的问题, 可以集中于两点:

 

1. 检索。

 

2. 有效。

 

关于1, 结构化的方法, 一般都是将内容与某一节点做一个映射, 信息提供者向这个节点汇报, 而信息查询者从这个节点获取。 同时, 这个节点的存在和同一,是通过“我们处于同一世界(物理上、时间刻度上)”这一事实来保证的。 除了实现细节的各种调整与优化之外,是不是真的没有改进的余地了?或者说,除了上述事实, 还有什么其它可利用的条件呢?

 

关于2, 分布式计算看似高端,其实反而可以含糊,因为只要不涉及远端计算机提供信息, 尚可以本地计算, 最终对一个可分解的计算来说, 仅仅是计算时间的问题; 信息传输要求稍微高一点,因为只要损失超过一定程度, 整个信息就是无用的; 而连续性播放则是比较难,但目前可以通过特殊处理解决。当这几者混合应用时, 问题可能会变得更加复杂一些: 多个部分的不同安排,可能导致可靠性在时间上的变化。

posted @ 2008-07-21 23:36 怪怪 阅读(396) | 评论 (1)编辑

交朋友的学问

交朋友这个事情是这样的, 咱们自己确实得努力, 否则有点水平的就不会倾向于和咱们建立关系。 不是别人骄傲, 而是如果交一大堆朋友, 用于交流的时间又有限, 到时候反而不知如何处理,得罪哪一个也行不是。

过去我玩Q3, 如果我在服务器里打的表现不错, 很多就要加我; 开始我是不会拒绝的, 但是QQ上人多到一定地步, 我开始没法弄; 最后即使我加了别人, 也不代表我会和他说话, 因为我必须隐身而且装的跟真的不在似的, 否则就别干别的了。但是我也有类似于全国前三那样的朋友, 为什么呢? 虽然我打不过他, 但是我有一些特色, 再练习中能够帮助他们提高。 这个开始我也不懂, 后来其中一人写文章和聊天时提到,我是他提高的三个阶段的最后一块踏脚石, 比如我的身法非常好,我才逐渐明白。

交朋友还有一些其他学问, 比如有一些人, 他即使不认识你, 你也可以把他当朋友。 比如对于我来说,这些人就是像Martin Fowler这一批。 当你把他们当作对话的对象, 你自然会提升的很快。 基本上, 在自己感兴趣的领域, 挑这么几个朋友, 所有你感兴趣的话题, 你都可以和他交流一阵子,Email吗? 不是, 就是很简单的他写过什么文章, 说过什么我怎么想; 我有什么看法,在同样的问题上, 他又怎么看。 在水平还比较初级的时候, 这种交流可以持续很长时间而且够用;真正的朋友能起的作用不也就是这些吗?

但是不要把那些真正高山仰止的人物当朋友, 因为说实在的, 没到一个级别, 根本无法做出这种交流。如果硬要上, 这样完全单方面的信息流, 会整个的毁了我们, 最后让我们彻底成为他的手下败将: 没有自己的想法, 只知道重复。 当然, 也许Fowler是我的朋友, 但还不是你的。 也许Anders已经是你的朋友了, 但还不是我的。 这完全取决于一个人和“目标朋友”的相对差距; 对这种人, 我们要承认他们是你我绝对意义上的老师, 但永远不要忘记一句话, 吾爱吾师, 但吾更爱真理。 总有一天, 老师变成了朋友, 虽然这不代表我们到了他那个级别, 但也有所小成了。

配合上面的“虚交”, 得到一些提高以后, 获得一些真正有联系的朋友, 也就是很快的事情。 因为人家会发现, 对他感兴趣的领域, 哪怕你还不是太够格, 但是也有一些自己的理解。 这样这些真朋友, 会愿意传授给我们他们的东西, 以期我们进步的更快一些, 也能回报给他们一些信息; 甚至我们暂时还不能给出回报也是有益的: 当他给你开讲的时候, 他也就获得了一次整理自己思路的机会。 但是, 绝对没人会愿意给一个完全不入门的人讲上好几个小时, 除非他打算去学校当个老师。

记住,最好的朋友是实力比我们高出一截, 但不至于太离谱的; 这包括真朋友和YY出来的朋友。前者一般是在一个数量级以内的,否则有联系方式也没用;后者的水平可以和你差距一个半数量级, 但不能更多了。在这之外, 交水平比自己低的朋友也是有益的, 标准基本上就是把上面的反过来; 但这一般是下意识就能做出的判断, 就不多说了。

posted @ 2008-07-18 14:03 怪怪 阅读(763) | 评论 (10)编辑

不需要强类型, 需要强测试?

     摘要: 这是Joel的观点, 据说, Bob大叔也是这个观点。 他们认为编译器的检查, 实际上就是编译期的测试。 而且他俩, 据说都达到了“测试成瘾”的境界。这就是说,他们抛弃过去对检查、尤其是静态检查的信仰。

Joel本人也曾一天到晚的思考, 是不是有一个最佳的方法,可以尽量少的付出代价, 尽量多的得到不同做法的优点; 不过他、Fowler、Robert Martin, 似乎已经都放弃了, 他们放弃的对吗?  阅读全文

posted @ 2008-07-18 06:19 怪怪 阅读(2062) | 评论 (21)编辑

一些待解的疑问

想了想, 还真不知道拿什么题目起头。 这样, 从以前的文章开始好了。

为什么OO是有本质缺陷的?


这篇文章中的疑问首先有这么一点: 静态语言中,我们如何能在改变一个系统内部接口的时候(注意, 不是对外发布的, 所以没有不能更改的问题), 只更改一处就解决问题? 比如最简单的, 一个类, 有Name属性, 是string的, 它对应某一个数据文件里的类似于表中一列的信息。 改变数据文件的结构,新添加了一个叫做Description的记录信息, 一个内部实体也增加了这个属性,我如何做到不修改从数据文件中读取, 和写入数据文件的代码呢?

毕竟, 这两个属性对这个数据文件的读写, 是没有什么差别的。举一个对比的例子, 在C++中, 我可以这样:

namespace fields
{
    
struct name;
    
struct age;
    
struct code;
}


typedef map
<fusion::pair<fields::name, std::string>, fusion::pair<fields::age, int>, fusion::pair<fields::code, char> > person;

使用时,我们这样使用:

person a_person;
at_key
<name>(a_person) = s;
at_key
<age>(a_person) = i;
at_key
<code>(a_person) = ch;

事实上, 这是使用fusion,稍微更改一下形式, 就可以变成这样: a_person.p<name>, a_person.p<age>。如果碰见变化, 修改一下typedef即可。 而我操作person的代码,只要其本身的逻辑没有变化,就可以做到一字不改; 因为我可以通过获取map中所包含的类型定义携带的信息, 直接写一个统一化的过程, 进行所有操作。 而如果使用OO, 第一个可以想象的就是, 每一个倒腾数据的逻辑, 无论是从哪儿到哪儿, 我都得加上对该属性的操作。

这个最大的好处是,只要在本质上是相同的过程, 我们只用写一遍。 另一个好处是, 我们同时具有静态语言的全部优势: 比如没有定义和包含description的时候, 无论你是at_key<description>,还是a_person.p<description>,根本就不会通过, 这样在非常大量的这种工作, 比起Dictionary和动态语言, 我们就可以避免大量的失误。

我想, 这个问题不能简单的用“很少有人用”来回答,因为它是结果。 首先它是方便的,而且方法名、属性名这种给人使用的死标记没有的缺陷它也没有。  那么我认为,没人用更多的仅仅是因为, C++和另外那些支持这种非OO范式的静态语言,其它地方太烂,是首先否定了语言上的选择, 所以也就没人在实体上使用这种设计和实现的方式。

当然使用Dictionary就痛快多了, 不过强类型带来的保障没了,这是不是缺陷呢?还可以使用反射完成相同的功能, 然后付出性能, 在我看来,这个性能就是缺陷的证明; 比如: 数据源是数据库, 那么有的ORM就用反射完成类似的工作, 但ORM的存在,反而证明了需求的存在。而且在ORM覆盖范围以外的数据复制和转移呢? 性能问题, 我们可以通过Emit来解决, 但Emit不是适合于所有使用情景; 而且, 我们就必须编写和调试大量的Emit代码, 额外的设施的使用和多付出的工作量, 也是缺陷的证明之一。

毕竟, 这些信息本来就是运行前已知的, 而且他们是有规律的, 也就是可以通过某种形式在运行前处理的, 同时可以通过合理表达自动化的。某人嘴里的“孟老头”对这个事情有他自己的理解, 现在就看某人的啦: 这是不是OO的缺陷?

posted @ 2008-07-17 12:16 怪怪 阅读(139) | 评论 (18)编辑

我来当个小人吧, To 关心博客园精华集的人、包包和搅风搅雨的人

     摘要: 现在我们所有人, 包括dudu、编委会成员、 出版社提供参考意见的同仁、 广大园子里的朋友, 首先要确定的一件事就是, 这些书应该是什么形式的? 也许甚至不同的分册不同的形式, 一切从实际出发。

除此之外,再无其它和人相关的冲突和矛盾。 再有人就这次具体事件, 针对某一个人或者牵扯进来的其它主体, 那就是找抽了。  阅读全文

posted @ 2008-07-17 03:34 怪怪 阅读(2957) | 评论 (138)编辑

两个过去的心得, 外加一个回帖整理

     摘要: 写程序、做设计是一个边学边干的活计,有一个著名的调侃, 就是如果程序员盖的房子, 你敢住吗?

广泛的掌握面向对象的手法, 但不要因为自己学了什么就给自己下套子, 那和屁股决定脑袋差不多。 学的这些东西是备用的, 大环境让我们必然能够用得上。 与此同时, 根据需求出发, 当自己有强烈的感觉, 某个学习过的东西, 能够解决当下的问题时, 再去试着应用。有的剑, 出鞘越少越好。

散文一篇, 不喜勿进。  阅读全文

posted @ 2008-07-15 05:56 怪怪 阅读(2289) | 评论 (22)编辑

WebResource备忘

已经不知道多少次掉进这个坑了....,一段时间不用就忘, 每次都得耽误半个小时。 这一方面说明, 这个功能的文档配合的不够好; 另一方面,真应了那句话,好记星不如烂笔头。

这就是: 资源文件, 如果放到目录里, 编译以后会被加上目录名....,这其实是必然的: 否则不同目录的同名文件如何处理?写到这,又推翻记性或者笔头的用处了。 因为这个事情太简单, 我反而没有琢磨这么基本的一个道理, 导致不能够在“哟?怎么回事”以后马上判断出是什么情况。不过这事也难说,也许我已经按这个思路想过, 不过还是没记住。 所以还是应该有做笔记的习惯。

顺便说点其它的。 Tag和Category这两个东西, 按理说本质差不多, 但这是一个朝三暮四的故事。 关键是你鼓励用户怎么做。

很多人认为Tag是随意的、即兴的,所以是私人的。 其实正好相反。 Tag其形式鼓励用户随便填写几个相关的短词,结果正是因为这样, 反而造成了不同的人写下的词可能是共同的, 于是这就变成了一个社区的、公开的、交流的、 把人和人、内容和内容相关到一起的公众的东西。仔细观察互联网用户,就会发现, 那些更加懂得如何*在互联网上*交流的同志, 会更多的用Tag,而且用的很准; 而比较嫩或者比较老的网民, 就会瞎写或者不写; 但即使瞎写, 也能增进和其它内容制造源的联系。

而Category鼓励用户仔细的去设置分类, 所以反而会突出人的个性。 比如同样对旅游这一件事,对A意味着很多内容, 对B也意味着很多内容, 哪怕这些内容大部分是重叠的, 仍然会因为不同的部分, 产生不同的Category表示方式, 结果这就成了两个分类。 而整个社区如果设置了分类,也仅仅是从网站出发,属于网站的个性为网站本身服务。假设一个网站有三种分类方式: 个人Category、全站Category、Tag, 这看起来完美, 但是会让用户最后哪个都不填, 因为太麻烦了。

当然, 真正实现Category和Tag的时候, 可以让它们产生极大的不同, 但即便是设计者, 实际上也是以“如何给用户一个导向”为导向的。 如果Tag本身能够组织, 形成图, 其实是一个非常有意义的事情, 不仅仅是相关性, 而是各种可能的关系都可以形成组织。 Category本身也可以极其强大, 而不仅仅是树状的模式。

实际上,一般的设计者区分两者的手段, 就是根据预期的导向,让其中之一在某些方面较弱, 而另一个在其它的方面较弱。 如果两个都强大到极端, 那么可以肯定功能是相似的。 但真正想清楚这些问题, 就会发现没有必要通过故意的功能性差异化去在系统内部作出区分。

只是在这个“两个都达到最强”的状态(或者可能是干脆基于一套内部模型的状态),反而要加倍注意用户导向的问题,这个时候可以通过界面、提示、交互方式等表面的东西来做出区分。 否则用户将会觉得迷惑和繁琐, 以至于放弃这些功能, 这对社区的组织者和内容发布者,都是一个损失。

还有点其它的本来想写, 不过还是别浪费时间了。 STOP。

posted @ 2008-07-12 09:45 怪怪 阅读(325) | 评论 (0)编辑

年轻人的未来在哪里?


posted @ 2008-07-10 19:32 怪怪 阅读(171) | 评论 (7)编辑

有一点我不得不思考的

有空了解一下OWL,看看是不是能给我的一些想法新的启发。初步的看, 似乎有点掺杂着一些不纯洁的概念。不过,Ontology的概念还是很明确的:

引用本體論譯自英文ontology,又譯存在論或是論,它是形上學的一個基本分支,英語詞ontology是來源於希臘語單詞ον(存在)和λ?γο?(學問)的組合。ontology主要探討存在的本身,即一切現實事物的基本特徵。

有的哲學家,如柏拉圖學派認為:任何一個名詞都對應著一個實際存在;另外一些哲學家則主張有一些名詞並不代表存在的實體,而只代表一種集合的概念,包括事 物或事件,也有抽象的,由人類思維產生的事物。例如「社團」就代表一群具有同一性質的人組成的集合;「幾何」就代表一種特殊知識的集合等。

ontology就是「研究到底哪些名詞代表真實的存在實體,哪些名詞只是代表一種概念」。所以ontology成為某些哲學分支的基礎。近年來,人工智 慧及資訊技術相關領域的學者也開始將本體論的觀念用在知識表達上,即藉由本體論中的基本元素:概念及概念間的關連,作為描述真實世界的知識模型。針對此一趨勢,W3C組織也開始定義了許多Ontology的相關語言,如RDF、DAML+OIL、OWL等。

为了统一性, 如果实现一门用于描述的语言, 可以忽略一个名词都对应一个实际存在这一分支, 而是加入一层, 认为每一个名词都对应满足一组条件的集合。 这样就和面向对象彻底分道扬镳了: 类也好什么也好, 只是一个方便我们组织和使用的别名, 没有更多的意义; 而每一个实体都是被用各种特征织起来的。 同时,面向对象中接口这样的鸡肋概念也可以去除, 而只检测一个实体是否满足条件。 这样, 静态语言的检查可以得以保留, 同时还可以延伸出自动推导等更高级的组织方式。

这也是我目前和脑袋的分歧所在, 脑袋更看重可行性, 认为借助CLR和保证与CLR上其它语言的兼容是必要的做法; 鉴于底层模型和其它语言接口要求的限制,这样就没有办法实现类似于C++模板的功能。 而我虽然更菜一些, 但是反而更“不切实际”,希望在这上面有所突破。 到底应该如何选择呢? 有没有变通的做法呢?



另外,早期和我有交流的, 还有我那失败团队里的家伙们应该知道,其实我的Web框架本身、框架想要支持的产品和当初我设计的商业模式, 基本上和后来从FaceBook开始的这一大堆平台战略相类似。 现在说啥都没劲了。 我需要考虑的一个问题是,到底是因为我进度慢, 还是这个事情, 小团队根本做不了? 说实话, 我不太相信后者; 我自己的分析是我的自我管理能力和执行力还需要锻炼, 对集中式应用缺乏应有的信念、对如何进入市场心存疑虑。

另一个具体的延误是,在Web框架到产品这一层, 对界面组装的灵活性和行为划分的严格性要求太高,而我一直没找到让我心满意足的设定,导致一直迟疑不决。从DNN到Weebly到现在的这帮家伙,人家更 NB的组织都知道先弄个能转的东西放出去再说, 我是不是太机械和2B了? 这个地方我很确定不是因为自己的技术无法支撑, 所以应该集中反思产品策略问题,“黄金圣斗士不会被同一招数击中两次”, 我想我需要谨慎的思考。当然,也不能一概否定: 如果不是这种性格, 我也不可能不断的获得很多思考和提高; 所以主要是,在哪儿较真, 较多少真的问题。



我到底是不是一个真正的技术人?

我想成为一个顶尖的技术人, 但:

1.这个想法, 是真实的吗?

2.我相当的能说废话, 一个说废话的人, 其性格适合做一个技术人吗?

3.我没有专精, 而是每一个接触的方面, 都达到比第一流差的那个水平, 这是一个好事还是坏事?

希望跟我有接触的朋友们, 帮我观察一下, 并提出建议, 越难听越好。

posted @ 2008-07-08 01:55 怪怪 阅读(789) | 评论 (4)编辑

昨天到今天也很高兴

     摘要: 作为技术人员, 我要把这本非技术的书, 放到SICP之前;作为德鲁克的崇拜者,我要把这本书放在《卓有成效的管理者》之前来;作为佛洛伊德、荣格的初步接触者,我要把这本书放在《梦的解析》、《现代灵魂的自我拯救》之前;作为巴尔扎克、陀思妥耶夫斯基的忠实读者, 我要把这本书放在他俩的一切作品之前;我甚至会把这本书放到老庄之前: 是的,这只是一本相当业余的小书,不乏一些不求甚解的成分,甚至也稍嫌肤浅且有点八卦; 但凡是围绕人的著作,没有一本对于一个像我这样的平凡人而言, 更加有实用价值了。

作为一篇全是八卦的博客, 我认为我有责任作为这本小书的枪手,把它推到首页,只希望其它人也能分享这份喜悦。 也许它并非完全和技术圈子是无关的: 很多兄弟对从业的感受和迷惑, 说不准能从这本书中找到答案。 这本书的名字叫做《遇见未知的自己》。  阅读全文

posted @ 2008-07-07 08:04 怪怪 阅读(3154) | 评论 (50)编辑

资料

http://en.wikipedia.org/wiki/Comparison_of_BitTorrent_software

http://en.wikipedia.org/wiki/Comparison_of_eDonkey_software

posted @ 2008-07-05 03:39 怪怪 阅读(1265) | 评论 (1)编辑

妈的

最近的一些感受。

首先,deerchao说的是对的, Community Server 2008要比2.1强太多了, 当然, 对于我来说还是不够好; 不过, 既然我自己没有能力拿出一个若干万行、并且好多人都在用的产品, 我就别他妈的JJWW了。 这件事的一个想法是: 有谁愿意提炼和修改Community Server 2008的,我愿意参与,我的想法是:

1.继续精简和重构。
2.改进对中文的支持。
3.重新开源之。

为了目标1和3,一些代码不妨重写。 这样的产品, 难说什么专利, 只要重构的程度跨过某一水平线, 版权不是什么问题。

第二件事, 我为了试一个软件是否存在时间过期, 调整了系统时间, 重启前也忘了改回来; 结果Windows 2008让我激活, 在这里提醒一下那些像我一样靠240天评估期使用非盗版Windows的同志。

第三件事, 重装的时候, 忘记旧软件应该先装, 比如Sql Server 2005应该在Visual Studio 2008之前。 有时候一些最简单的事情也会犯错, 所以细心和把细心的结果形成习惯,还是必要的。另外, 了解了一下Installer安装组件和Hotfix的思路, 发现一些问题还真是难处理;初步感觉,其实我们自己设计真正的软件时,也可能会碰见类似的问题,看看能不能沉淀一下,变成可以触发的联想的知识和经验。

第四件事, 我决心调整重点, 把Web框架作为次要工作了,我现在就必须开始P2P的研究。 从06年年底开始到现在, 一直没进入真正的产品阶段, 我想这绝不光光是因为我懒, 而是存在深层次的问题。 分布式、非集中的网络,才是我的信仰;我是不是真的愿意做Web框架,还是因为从事过一些Web开发就习惯性的走到这个道路上,我没法去分析清楚。

但是我自认对Web开发的方方面面,有一些体会还是很准确的。我希望我的实验成果还能为别人发挥一些作用,所以我还会把它当作一个副业继续。也许这样,心态反而会变好,作为一个副业,效率比这1年半还高也不是不可能的事情。

关键是了解自己,管理自己,这才是重中之重。

Update:
多加一件事, ATI的程序员不是人。 就是因为有了这样的程序员, 一般群众对.NET的印象就越来越坏。

posted @ 2008-07-02 07:53 怪怪 阅读(2220) | 评论 (9)编辑

最近回帖整理:

原帖,针对第四点:

看看客户所说的话, 能不能整理为一个自然语言的子集:与业务相关的小语言,并形式化。 实现过程可以三步走:

1. 对需要变化的业务规则建立统一的模型。

2. 使用解释器模式配合配置文件来表达小语言,应对变化。

3. 当2变得复杂和难于掌握, 考虑实现一门业务小语言, 难度较深。

纸上谈兵, 没机会实战过, 而且我估计这个成本对于承接项目的公司恐怕难于接受; 除非在市场上有多家公司需要这种东西, 这样算是预支成本吧。

对于一般技术人员, 可能认为难度在于实现小语言。 其实最难的一部分是如何将业务规则及其变化归纳为一个可接受的表达形式。

posted @ 2008-07-01 06:17 怪怪 阅读(2224) | 评论 (4)编辑

怪怪论三国:到底该关注些什么

发现博客园对三国感兴趣的人很多,不过关注点似乎和我都有所不同。要是让我看,三国时期只有一个英雄那就是曹操,除此之外就只剩下层次高低不等的流氓及其团伙一干人等。说实话,曹操身上最大的一个弱点,或许就体现在“天下英雄唯使君与曹尔”这句话中了,这说明他的精神境界中还有一些和刘备一样低劣的东西,如果曹魏最终的衰亡真有曹操自己的因素的话,恐怕就在这里了。

有人说三国志中曹操传比别人长比别人详细, 是因为作者以魏为正统, 个人不以为然: 比较一下职业生涯中,在动作的大小和频率方面,刘孙与曹操之间存在的不可弥补的差距, 就可以知道刘备、诸葛亮等作为与日月争辉的星星,不过尔尔。 有兴趣的, 以对于孙刘而言是大动作的粒度, 对曹操阵营的动作做一个列表, 比较一下三者的长短, 再配合时间轴一看, 这些都一清二楚。 这个故事本来一点也不复杂, 只是后面那些只知道拿三国吃饭的学者们把它弄复杂了。

很多人关注三国,着眼于做人,比如曹操所谓的权谋, 这实际上只是旁枝末节。 曹操此人身上所蕴含的巨大而无可匹敌的能量,才是真正无法忽视的根源;即使他做事方法变一个样,结果也不会逆转。 曹魏的命运, 也许可称的上“天亡我, 非战之罪”。 这个问题我没有足够的知识与能力关注,只说两点: 曹虽然起家于官宦家庭, 但其势并不比陈胜吴广项羽刘邦更好;客观历史环境所导致,那个时代的创业者比任何一个其他时代需要做都要多,以他的寿命是无法完成的。

要说做人,我们真正要看到的是,曹操做事情的节奏;我们还不能忽视的是, 无论作为政治家、军事家、社会活动家、文学艺术家,曹操的杰出成就的总和,可以说在中国历史上是数一数二的。 就像数学家标榜的“人类心智的荣耀”,和所有那些取得成功的人所真正留下的宝贵财富别无二致的,他的一生展示了一个人可以达到的极限有多远。 有些人可能认为,像文学艺术这样的东西,和曹操的成功失败没有必然联系,但事实上,正是曹操的内涵决定了他是一个什么样的人。

那些只注意权谋、机巧的人,是不可能走上和刘邦、曹操这样的人一样的道路的。 简单地说,像他们这样的人,好比上了发条的机器,没有停止的时候;而且他们通过训练,可以让动力衰竭的速度,控制在一定的范围内。当一个人在一条道路上,相对时间相展开到绝对时间上比其它人多好几倍,他注定要比所有人强。 这才是历史给我们上的第一课,没有这一课,纯粹的认为(类似的)老毛之所以是大家的头儿,是通读了二十四史或有什么其他杰出才干,是毫无意义的。

孙武告诉我们说,以正合、以奇胜,这已充分说明了孰在前、孰在后。 把周遭的人和事情想的特别复杂,并且和历史对照,在我们有足够的“正”之前,未必是什么好事。作为我们文化历史中的重要组成部分,对刘关张和诸葛亮的褒扬,对曹操“奇”的一部分的过多关注,过去几百年来对我们的民族是贻害甚巨的;这种传统掩盖了最重要的东西:如果一个人没有掌握真正的内在因素,就沉迷和训练自己什么做人、领导的艺术,哪怕就是极端的小人也不能成为合格且成功的大坏蛋。

我们首先要注意的是那些不平凡的人身上积极向上和光辉的一面,他们告诉我们一个人通过自身的努力可以换来什么样的奇迹,这才是属于全人类的骄傲。虽然作为一个普通人,拿我们和BT相比似乎没有什么意义 -- 但我认为,这些才是每一个想改善自己,取得更大成就的人所要关心和学习的; 至少借由这种鼓励,我们可以去尝试突破自己, 这才是真正的榜样的力量。

posted @ 2008-06-29 08:35 怪怪 阅读(3947) | 评论 (49)编辑

闲逛, 看见这么一句话

很随机的不小心进入网上一个不知名的博客,其随笔里提到的,他似乎是个经济学的研究生什么的。

此人说道我站在马克思的“生产力决定生产关系,生产关系制约生产力的发展”的观点上去解释组织的起源,而非交易费用节约的角度,交易费用节约只是组织的功能,拿功能来解释起源就犯了“功能主义”的错误。

嗯嗯,有意思。很显然我没必要去和他比他们领域内的知识和能力啦,不过还是有些额外的思考。

过去我也是信马克思的,而且,“生产力决定生产关系,生产关系制约生产力的发展",这一简单基本的观点,我现在也在用。但是随着我自己的世界观的形成,我似乎开始有了变化。
使用新的世界观,就不会简单的给不同的角度扣上各种大帽子。从交易费用节约的角度上看,真的是所谓的功能主义吗?即使是,功能主义背后所隐藏的东西,会不会比马克思的观点更朴素更基本呢?

有一个防雷的经验,就是说,如果在雷电击中你的那一刻,你抬起的是左脚,你比较不容易被电死。说实话,我是一个驽钝的人,想了好一会儿才明白为什么:电流想要流入地面,必须从右脚过去,这就有一定概率让电流避开心脏了。但我们不要忘记另一个事实,雷电是击穿空气打到你身上的,那为什么它不击穿你左脚和地面之间的空气呢?

这个道理非常简单,上过初中就学过,电流倾向于从电阻更小的地方通过;由于空气的电阻大大大与我们身体的电阻,它不会去选择击穿空气。我这些描述,细究的话,错误百出,而且很不严谨的拿电流当作了主语;但它在大体上是那么回事。这体现了一个非常基本的规律,就是能量最小耗费的原则;同样,作为更适合当主语的人,如果在获取的信息足够的情况下,我们也会执行最省事的一个方案。

我们可以考虑,如果人类和电流没有这种共同性,恐怕在物竞天择的自然界中,我们早就被淘汰了。所以我们可以认为这是宇宙本身的意思,它告诉电流那么做,也告诉我们该怎么做。我们并不需要高深的哲学和复杂的科学,只要愿意去多了解一些,就可以很不严谨的建立起一套正确概率还算不错的指导方针。

马克思的观点在这里,其实恰恰不是原则,而是结果。
我们把“组织”等同于某一种生产关系, 这种生产关系之所以产生,必须符合来自宇宙的指导,这些指导之一显然就包括能量最小耗费原则:我们可以想象,一些领域内活动(不止交易),在某一生产力和其它可能存在的条件下,一种生产关系会比另外一种生产关系更加节约,那么节约的那种生产关系就会屏雀中选。

我这样的说法,和单纯的交易费用节约又有很大不同,但是仍然可能是功能主义的:因为实际上是“节约”这一功能在前,生产关系的起源在后;是为了节约才有组织,而不是有了组织才节约;如果浪费是组织必然行使的功能,组织这种生产关系还能有起源吗?这也就是亚里士多德所说的目的因。另外,我对它的使用本身,就符合了能量最小耗费原则:针对我所需要掌握的程度,这种解释方式可以让我使用更少的能量去琢磨它。

马克思的总结中,还有一些其它因素,比如生产力,为什么生产力会发展呢? 马克思怎么回答的我已经忘了,但我也有自己的答案,不过,那就是另外一个故事了。总而言之,“生产力决定生产关系”这样的结论背后,其实可以挖掘的东西很多,如果纯粹把它本身当作一个锤子,看什么都是钉子,就非常有问题了。

最后多说一句,我不是唯心主义者,仅仅是选择了这样描述。

posted @ 2008-06-28 06:49 怪怪 阅读(2526) | 评论 (10)编辑

从DDD说开去,流行方法论和我们的未来

     摘要: 也许这就是人类做事的解决之道: 既然我们的社会还不具有一大堆能够将现实世界的问题和真正艰深的科学理论联系起来的顶尖工程师,也没有出现一群真正的大师拿出对大多数问题解决方案的总结,而事情总是要做的, 那么不如一步一步的来, 让菜菜鸟们跟随菜鸟的优雅,采取次一等的做法总是要比什么都不做来的好得多。所谓山中无老虎, 猴子称大王, 就说明大王存在的必要性了。  阅读全文

posted @ 2008-06-27 05:17 怪怪 阅读(3793) | 评论 (53)编辑

路过的说说, 我那篇文章, 应该发么?

说实话我有点疑惑, 不知道这样做对不对, 虽然那是我的真实想法。

这东西有趣。 设计产品的都去看看。

http://blog.seattlepi.nwsource.com/microsoft/archives/141821.asp

是一封披露的电子邮件, Gates讲述了在Microsoft.com下载Movie Maker的可怕经历, 以至于写了这个邮件敦促改进。 如果Gates都是这个感受, 那么我们设计产品时应该什么样呢?

posted @ 2008-06-26 23:57 怪怪 阅读(1077) | 评论 (0)编辑

也谈优秀: 我们真的必须知道什么吗?

     摘要: 工程人员绝对不要期望自己像研究人员一样生活和工作, 一旦达不到就抱怨。 要知道我们的工程时间, 和我们的生命都是有限的, 而一个工程人员有做不完的事情。如果不停的学习, 大多数时候不过是从一个表面到另一个表面的浪费时间, 所谓的“深入”,不过是个自我欺骗的屁话。   阅读全文

posted @ 2008-06-24 18:24 怪怪 阅读(3939) | 评论 (51)编辑

临时笔记, 有意思的东西

一些编译器理论的简单介绍,和现代Parser研究的新进展。

http://www.antlr.org/article/needlook.html

http://citeseer.comp.nus.edu.sg/440034.html

Tomita(GLR) Parser

Packrat parser (use TDPL)

http://java.sun.com/docs/books/jls/first_edition/html/19.doc.html

http://www.cs.berkeley.edu/~smcpeak/elkhound/

http://www.mollypages.org/page/grammar/index.mp

http://lambda.uta.edu/cse5317/notes/node20.html

http://pages.cpsc.ucalgary.ca/~robin/class/411/LR.1.html

http://en.wikipedia.org/wiki/Memoization

http://en.wikipedia.org/wiki/Comparison_of_parser_generators

http://en.wikipedia.org/wiki/Parsing_expression_grammar



> The author states that he wrote the GLR parser generator solely to
> handle C++ language spec [and someone lapped it up to handle Java].
>
> What exactly is it about OO languages that an LALR(1) parser cannot
> handle?

As the moderator noted, there is nothing about "OO" languages that
LALR(1) parsers cannot handle, but C++ itself is problematic. There
are LALR(1) and LL grammars for Java.

One of the problems with C++, is that expressions and declarations can
look exactly the same (technically, any language containing those the
or of the two productions is ambiguous) and C++ gets around that by
saying, if it looks like a declaration, it is a declaration (forcing
the "or" to be resolved in a particular declaration (and resolving the
ambiguity). However, that resolution is not expressed gramatically,
and one can not take two random context free rules and difference them
and expect the result to be a context free language, which is what the
C++ ambiguity resolution requires one to do.

In contrast, GLR grammars are not required to be unambiguous. Any
ambiguity is resolved by producing a resulting parse-forest that
represents all the potential mabiguous choices and requiring a later
"semantic" pass to choose which parse tree in the forst is the desired
one. Thus, with a GLR parser, one can disambiguate the C++ problem by
selecting the parse tree that treats all the ambiguous expression/
declaration sub-trees as declarations.

The only problem with GLR as a technology is that are no "warnings"
from the grammar processing tool that the language is ambiguous.
Well, there are warnings that the language is not LR (or LALR) or
whatever technology the GLR parser uses as a base. However, some of
those grammars will actually not be ambiguous and some of the will be
ambiguous. However, in any case, once your GLR generator has given a
warning, one either must prove that the language actually isn't
ambiguous or write your semantic phase assuming that the language is
ambiguous and disambiguate the resulting forest.

It is worth mentioning that there are other ways of handling ambiguous
grammars. In particular, one can use predicates to resolve
ambiguities. Predicates allow one to take the difference of two
productions in a controlled manner. In particular, it is possible to
write a syntactic rules that says, try to parse this as a declaration
and if it isn't parse it as an expression. The difference between the
predicated and the GLR solution is that predicated grammars are still
deterministic. There are no hidden ambiguities in a predicated
grammar. If your predicated parser generator gives you an error, you
still have an unresolved ambiguity and if it doesn't the resulting
parser will always construct a parse tree (and not a forest).

I would be remiss if I also did not point out backtracking parsers,
which are another solution to the problem. In fact, all the
implementations of predicated parsers that I know of, use some form of
backtracking in their implementation. General backtrakcing parsers
share the characteristic with GLR parsers that they can parse
ambiguous grammars. Backtracking parsers generally also produce a
parse tree (although in theory they could also produce a forest).
Backtracking parsers have their own deficits though. Many
backtracking parsers will loop forever on some ambiguous grammars.
(Predicated backtraking parsers do not generally have this problem,
although they do not make the same linear time guarantees that pure LL
and LR parsers do(see note)--of course, any parser generator that can
handle a significant class of ambiguous must be inherently non-linear
for some grammars, and GLR parsers have a cubic worst case, same as
Earley parsers.) In addition, most backtracking parsers resolve
ambiguities by selecting one parse tree out of the forest to return.
This is generally done by the order of the rules in the grammar (which
determines the order the rules are tried in in ambiguous cases). If
one looks closely, this is very similar to using predicates
"implicitly" in the grammar. The key difference being that the tool
inserts the predicates rather than the user and does so without
warning and usually without the run-time termination guarantees.

I would like to mention that it is possible to build a predicated
parser using GLR technology, although I don't know of anyone
attempting to do so right now. From thought-experiments I have done
considering whether to implement such a tool, it seems like there
would be some advantages to building such a tool.

Again, I do not want to imply that these are the only techniques for
dealing with ambiguity. For example, Ralph Boland is pursing some
generalization of LR technology that I gather will handle a wider
class of languages and I don't think his technique is any of the
above.

Note: Bryan Ford recently published a paper on a "predicated" parsing
technique that made extensive use of memoization and lazy evaluation
to achieve (if I recall correctly) a linear time guarantee. His
technique shares a characterisitic with general backtracking parsers
in that the order of rules determines what is matched and the the
entire tree is disambiguated that way. He uses an "ordered" or clause
to implement this.

Hope this helps,
-Chris


Chris Clark said (in part):

> It is worth mentioning that there are other ways of handling ambiguous
> grammars. In particular, one can use predicates to resolve
> ambiguities. Predicates allow one to take the difference of two
> productions in a controlled manner. In particular, it is possible to
> write a syntactic rules that says, try to parse this as a declaration
> and if it isn't parse it as an expression. The difference between the
> predicated and the GLR solution is that predicated grammars are still
> deterministic. There are no hidden ambiguities in a predicated
> grammar. If your predicated parser generator gives you an error, you
> still have an unresolved ambiguity and if it doesn't the resulting
> parser will always construct a parse tree (and not a forest)

I agree with Chris about the use of predicates.

Interestingly, the use of predicates alone can some Type 1 power to a
grammar.

For instance:

L1 = {a^n b^n c+} // clearly a type 2 language
L2 = {a+ b^n c^n} // clearly a type 2 language

L1 intersect L2 = {a^n b^n c^n} // a type 1 language

Current research in the area of this class of grammars can be found here:

http://www.cs.queensu.ca/home/okhotin/

See the section on "Boolean grammars." Intersection can get quite a bit of
power out of a formalism.

My most recent paper deals with several difficult to parse languages of the
classical sort, including the particularly nasty to parse:

L = {a^m b^n c^mn}

The only grammar I've seen expressed for that one in classical form is in
Type 0 due to a length increasing production:

  (1) <S> ::= <H><S> | <H><B>
  (2) <B> ::= <B><B> | <C>
  (3) <H><B> ::= <A><X><N><B>
  (4) <N><B> ::= <B><N>
  (5) <B><M> ::= <M><B>
  (6) <N><C> ::= <M>c
  (7) <N>c ::= <M>cc
  (8) <X><M><B><B> ::= <B><X><N><B>
  (9) <X><B><M>c ::= <B>c
(10) <H><A> ::= <A><H>
(11) <A> ::= a
(12) <B> ::= b

Because production (9) is length increasing, the grammar is in Type 0 form,
even though the language itself is Type 1. I'd like to see that grammar
normalized to a Type 1 -- but haven't been able to find one.

The longest derivation I've been able to do with that by hand is aabcc,
which is:

(11) aabcc --> <A>abcc
(11) <A>abcc --> <A><A>bcc
(12) <A><A>bcc --> <A><A><B>cc
  (9) <A><A><B>cc --> <A><A><X><B><M>cc
  (7) <A><A><X><B><M>cc --> <A><A><X><B><N>c
  (4) <A><A><X><B><N>c --> <A><A><X><N><B>c
  (3) <A><A><X><N><B>c --> <A><H><B>c
  (9) <A><H><B>c --> <A><H><X><B><M>c
  (6) <A><H><X><B><M>c --> <A><H><X><B><N><C>
  (4) <A><H><X><B><N><C> --> <A><H><X><N><B><B>
  (2) <A><H><X><N><B><B> --> <A><H><X><N><B>
(10) <A><H><X><N><B> --> <H><A><X><N><B>
  (3) <H><A><X><N><B> --> <H><H><B>
  (1) <H><H><B> --> <H><S>
  (1) <H><S> --> <S>

I started on aaabbcccccc -- but got lost in the shuffle. :-(

If anyone wants to try a purely "predicate" approach to the above
language -- I'd love to see it. (Or if anyone would care to post the
derivation of aaabbcccccc, I'd really love to see that, too.)

The $-grammar I wrote for that one accepts strings in O(n^2.3), and has 6
productions and 2 of those are predicates, but also makes use of 2
phi-expressions, which implies a total of 4 predicates (since there is an
implied predicate with every phi-expression) and at least 2 name-indexed
tries.

Also of note is that I allow for a-expressions in predicates, which allows
for substrings that have been parsed to be concatenated to form entirely new
input that is then passed to the predicates. (The $-grammar for a^m b^n c^mn
uses this.) This is similar to what is known as "length-increasing".

Anyway, a few nights ago, I was asking myself about this formation in C++:

class Foo
{
int inline_function(int x)
{
return __y * x; // __y is used before being seen
}

int __y;
}; // this class is legal

class Bar
{
int inline_function(int x)
{
return __y * x; // __y is an undeclared variable
}
}; // this class is not legal because __y never gets declared

$-calculus was able to handle this ... without any code, accepting Foo and
rejecting Bar -- using all of the above mentioned techniques.

Although the resulting $-grammar uses more than 1 explicit predicate, it
does make use of phi-expressions, and these have implied predicates -- so I
was not able to do it without extensive overall use of predication.

Anyway -- I wrote it up and am looking for somewhere that is looking for a
3.5 page paper on such things. Any thoughts?

[BTW -- Chris -- direct email to you bounces from my account. Is that a spam
guard?]

posted @ 2008-06-20 20:30 怪怪 阅读(1775) | 评论 (0)编辑

方法级AOP: 又一个补丁

     摘要: 方法级的AOP的一种办法, 利用了新的Expression, 比起生成动态代理类那是清凉多了, 使用起来也灵活, 就是表达方式有点丑 :P

这是跟老赵还有脑袋讨论的成果, 感兴趣的可以进来讨论一下。 感谢老赵和他的文章的帮助, 同时也更深刻的感到如果语言的表达方式能提供足够的支撑多好, 大家一起催脑袋干活 :P  阅读全文

posted @ 2008-06-12 23:54 怪怪 阅读(4491) | 评论 (19)编辑

     摘要: 绝对有另你不适的内容, 不想反胃勿进; 基本上是一篇可以定性为“反人类罪”的发泄。  阅读全文

posted @ 2008-06-02 04:11 怪怪 阅读(4950) | 评论 (10)编辑

系列讨论初步考虑的备忘

     摘要: 先把一些相关的内容, 想到的目录记录一下。 这些标题是散乱的, 甚至不是一个层次的, 仅仅做一个备忘的笔记。

顺便说一句, 这个系列不是忽悠大家去用某一门“表达方式更丰富”的语言, 或者给出什么解决方案。 对于大多数程序员, 身处环境和项目当中, 更换语言是不现实的。 更何况说实在的, 现在还没有一门语言能够完美的达到我想要的效果或标准; 即使那些能够做到的语言, 我们可以采取的表达方式也是极其丑陋的。 并且, 在这系列文章的讨论所涉及的一些工作,如对语言本身的改进, 也不是大多数程序员任务。

但是我们仍然可以因为一些深入讨论, 知道问题的症结所在; 从而在能避开的时候避开, 在不能避开的时候, 不会殚精竭虑的去寻求不切实际的解决办法。 同时, 在这个系列中, 我们也可以找出一些外围辅助的方式处理好其中一些问题, 暂时不能治本, 指标也好。 更多的, 我们可以通过讨论,把现今那些浮躁的解决方案先放到一边,努力的去试着看清未来10年一些可能发展的方向。如果10年之后, 你我还在做技术, 即使没有预测准, 这样的尝试也不能说是无意义的。
  阅读全文

posted @ 2008-05-24 09:14 怪怪 阅读(5611) | 评论 (16)编辑

保存个地址, 顺便问个问题~

再更新两个地址:
http://programmersatwork.wordpress.com/john-warnock/
http://programmersatwork.wordpress.com/bill-gates-1986/

更新一个地址: http://www.infoq.com/articles/dsl-on-the-clr

地址: http://www.codersatwork.com/names.html?order=popularity

最后这个是个大牛列表 :)

问题:

具体点拿一堆图片的管理来说, 大多数系统, 都是有一个Picture表, 一个Category表, 一个链接表, 链接表就这两个字段: PictureID, CategoryID。

比如任何一个相册, 用户可能给一张图片一个分类, 但是也可能没给这张图片分类,这些没有分类的图片, 在咱们实现的时候, 是让他们属于“没有分类的图片(或默认分类)”这样一个分类呢?还是就让他们什么也不属于: 凡是用户没有指定分类的, 根本不在链接表内出现。

对应于数据库, 对于用户没有选择分类的情况,这两种做法区别在于在链接表内, 会不会有 {PictureID = 1 CategoryID = 默认分类ID值} 这样一行。

有默认分类的优势在于当用户查询“所有没有分类的图片(或默认分类的图片)”的时候,一句"Where CategoryID=默认分类ID"搞定了, 而且可以统一处理“没有分类,分类1, 分类2....”之间的区别。 劣势却仅仅是我的链接表里比不设立默认分类, 多出很多行。

我的想法是, 是否可以把设立默认分类当成一个最佳实践,无论建立什么系统时, 只要在实质上是一个分类的问题, 都可以采取这种实现; 因为这个问题普通到不再受其他条件的影响。 问题在于有没有不适合的反例,比如有默认分类在某种情况下更糟糕, 我想问的就是这个。

这个问题虽然简单, 不过从我第一次接触到现在7、8年来, 一直没有着急做出判断, 也是不敢轻易判断。 因为我无法判断从事情的本质来讲, 没有分类是不是就是一种分类; 这个问题和0到底是不是规划到自然数有点像; 所以对于我来说,这个问题的答案, 对我认识事物也许会造成连带的影响。

那么如果不说这些虚的, 光从实际出发, 设定一个叫做“没有分类”的分类来简化问题, 是否有存在着不适用的反例呢?

posted @ 2008-05-23 12:31 怪怪 阅读(5037) | 评论 (7)编辑

嗯嗯, 今天很高兴

今天(或者说昨天),见到了AnyTao、周银灰、丁学、 金色海洋、 jilzhang几个兄弟, 不过有一点不爽, 因为昨天休息不好, 老毛病又犯了, 一困就要滔滔不绝的说话,这个可能妨碍了大家更好的交流。 最后都到了我和丁学的大本营, 我还抑制不住兴奋, 拉住他又说了一根烟的废话, 完全没考虑到明天人家还要上班。 在这里向大家致歉。

jilzhang说的不错, 我写文章没有重点, 乱七八糟的东一句西一句, 我考虑是不是以连载或者书(不是出版的书)的形式, 把篇幅拉长, 并且根据我所表达的食物的前后依赖关系进行规划, 然后按部分阐述, 这样是不是能清楚一点。 还是怎么样, 希望大家多给我提提意见。 说实话, 就像大家说的, 每个人发文的积极性也有限, 如果我始终不能提高自己的表达水平, 可能也不会一直这样一团乱麻的继续下去。

还有, jilzhang对持续集成的实践的介绍, 破除了我因为不喜欢Fowler而对CC的反感, 这是一个收获; 我会找机会试试这个东西, 幸亏一直以来我对不熟悉的东西不会评论, 不然如此情绪化会影响正确的判断力。 大家也打破了我想办法混个更高的学历从而当个老师, 以赢得研究时间的不切实际的想法。 这几天我会思考一下, 是不是还是以应用出发, 带动研究。

说实话感觉在程序设计的哲学与表达上, 我应该有一定积淀去支撑我所中意的几个应用了; 反过来讲, 语言设计和编译器技术倒不是很着急的事情, 因为和那些语言作者相比, 我似乎还缺乏很多的体会, 包括制造一个语言的需求。 本来这些应用就是肯定要做的,也许我应该切掉好高骛远的期望, 针对目前可行的应用,全力以赴。 也希望能以这些实践为依据, 更清楚的表达我的理念和具体实践方法。

从AnyTao和丁学那里, 初步了解了某一个敏捷形式过程中的一些重点, 包括如何和客户打交道的经验等, 受到了不小的启发; 这些东西都是我目前的工作生活状况很难接触到的。可惜周银灰和海洋没我这么爱说话, 不过还是从海洋那里初步了解了他的思路。 并且, 一些海洋式的反问, 对我的牛皮也是很好的质疑, 让我注意到我对我的理论的实践和思考, 还存在着不少模糊的点。

总而言之, 今天是不错的一天。

posted @ 2008-05-19 01:51 怪怪 阅读(4749) | 评论 (10)编辑

为什么OO是有本质缺陷的?

今天我在这里说OO表达能力不足, 估计没人会信, 但是这真有可能是问题的核心所在, 如果是这样, 那么用歪了也罢学习困难也罢, 错不在使用者和学习者, 而在于OO自身(这种质疑也不是一天两天了,不过大多数言论都是外延法,强调主观因素, 所以不具说服力)。

这篇文章中的思路首先要归功于songcan兄弟刨根问底的精神和脑袋兄与我的讨论和对我的帮助。

废话少说, 说个关键问题吧。 OO最常见的就是 Teacher.Students, Teacher.Speak(), 也就是说Students和动作Speak作为Teacher的组成部分, 是我们关注的切实存在的概念, 但传统的OO居然没有给出向*系统*描述这个概念的表达方式。 是的, 你我都理解字面意思Speak, 可问题是这个概念在系统内不能表达, 我们就无法用其它机构来处理这些概念。

为什么C#加入delegate以后, 方便了许多? 因为Speak从某种意义上, 可以单独提出来, 作为一个在系统中的实际存在, 并且开始可以对它进行有限的操作了。但这还远远不够, 因为Speak是作为Action()存在, 它自身在业务中的独特性没有特别好的方式去表达。

另外一点就是动静间的鸿沟。 C#在Strustroup这些人的看法里, 并不属于真正的静态语言, 但是它给出了一个静态的外表。当我们进行描述时使用的是静态的方式, 我们就必须有静态的方式处理它们, 否则这里面就存在裂缝。 如果大量的反射, 那么我们何必不直接使用动态语言呢?

JS大家都接触过, 比如

obj["someAction"] = function() {}
obj.someAction()

那么C#拿着反射出来的MethodInfo搞来稿去,和JS的方式比丑陋的多, 这样的方式有必要去学吗? 如果一门静态语言, 大家越来越多的是在使用这些, 或者通过那些框架、工具间接的使用这些, 这难道说明这门静态语言, 或者基于这门语言的OO方法, 越来越强大不成? 只能说这种方法因为自身的问题, 无法继续提供足够的支撑了, 不得不求助于外部设施。

说实话, 如果一个语言, 表达重要的概念用到的那种表达方式, 比如类型, 它本身不能被操作的话, 那么它存在问题是必然的。 C#可以操作, 但提供的主要操作方式, 都在运行时, 通过反射。 可我们表达概念时, 却在编译前, 也就是说我们的表达注定是不完整的(或不直接的)。 反观动态语言, 为什么越搞越火, 还不是因为人家干脆都放在运行时了, 完整了; 而且在表达方式上优化过, 直接在语言层面支持, 这不是反射所能比的。

如果我每句话缺几个字, 大家感觉如何? 一个不完整的表达, 你觉得什么样的工具或者方法论, 让你能够毫无障碍的完成模型的建立呢?

P.S. 再次感谢以上二位和与我讨论过的各位。

另外, F#我也试过了, 这些问题全部存在(妈的,终于理解SICP某一页的小注释中质疑流行语言的类型系统的原因了), 根本是白搭: 实际上这本来与是否FP也没啥联系, 只是我希望作者按照脑袋兄跟我提出的那种意图和方式, 在编译器的层面做了一些改良。我的最后一线希望成了梦幻泡影。

我现在的建议是,要么选择一门动态语言, 要么选择C++和D(其实C++是个很差的选择); 如果暂时不能更换, 那就不要考虑太多了, 承认问题的存在, 并且尽量弥补就是(似乎.NET平台上的语言目前就是这种状况, 我自己也是在鉴于现实原因没法换的境地)。

最后重申一遍: 不要因为OO存在这样那样的问题, 就放弃OO的尝试。 我的想法是, 作为一种当代最流行的方法, 没有一定程度的了解是不行的, 就像牛顿定律一样。 所以我倒是认为, 对OO的深入思考和练习, 虽然一时疑惑, 也绝非没有好处的; 尤其是当我们知道它可能存在问题这一点, 就更可以放开心态了。

过去一个高人对我说, 想学好数学先学好数学史; 我数学史不咋地。 今天我要说我们有一个大好机会, 因为我们就在历史里(这个历史看来还要持续几年); 如果我们认为OO不过是个大忽悠,不屑于学习OO体现了自我相对于云云大众的明智, 那么明天会如何, 就不好说了。

剩下的, 就是等脑袋兄的编译器小改款出炉了, 大家一起拿鞭子抽他干活...

posted @ 2008-05-17 07:31 怪怪 阅读(3670) | 评论 (9)编辑

漫谈数据存取与对象设计

     摘要: 本文介绍了几个问题的某些特定的解决方法, 除了这些方法, 还有很多其它的方法。 要不要使用它们,关键在于我们对碰见的情况是如何判断的。 只是一概而论却忽视了衡量必要性、 适用性的工作是不行的; 进行判断的时候, 忘掉所有的面向对象原则和建模指南吧。 另外一个情况就是, 也许“程序本身需要组织和管理”的需求是突然发现的, 重构这一话题的流行,也足以证明一开始就固定一个漂亮设计的风险。

这也是一般程序员的饭碗所在, 如果有一个一劳永逸的方式, 那么它很容易被固定下来, 减轻工作量,可也意味着这些地方不再需要程序员了。  阅读全文

posted @ 2008-05-13 20:05 怪怪 阅读(3148) | 评论 (27)编辑

晕了

没事又琢磨下DLinq, 顺便关注了下Entity Framework, 总感觉是走在了错误的道路上。

整体工作量并没有下降多少, 而复杂度却在上升; 效率没有上升多少, 而灵活性却在下降。

如果说大公司是吃屎的, 跟随的都是挨忽悠的,这不是我的作风。 不是怕得罪人, 而是不客观。

我像是裸泳的吗? 糊涂中。

Update:
说点题外的, 很可能大多数时候我们对一件事物的执着来自于自我价值肯定的心理需求。 这种心理需求用好了,是成就自己的动力; 用坏了,就容易产生误导自己的错觉。

所以要谨慎、 谨慎、 再谨慎。看似针对外部问题的判断, 有时候恰恰需要仔细衡量的是我们的内心。

Update:
有个可以类比的思考: 我们刚接触ASP.NET的时候, 甚至DreamWeaver的时候, 感觉一切托托拽拽多么简单; 最后呢?

隐藏复杂度不等于更好的掌控了复杂度, 转移或转化问题不等于真正的减少了问题。

剩下的就在于如何分辨两者了。

posted @ 2008-05-12 11:41 怪怪 阅读(1075) | 评论 (8)编辑