已锁定 主题:Why OO sucks
该帖已经被评为良好帖
|
|
---|---|
作者 | 正文 |
发表时间:2008-08-21
inshua 写道 buaawhl 写道 闭包是FP语言的一种携带数据的迫不得已的方案。而且,不能“定义”类型,只能动态“产生”类型。 闭包产生类型,不如OO定义类型那么直观和便利。 实际上也可以定义类型。拙文 new 是什么 this 是什么有指出,见 http://blog.csdn.net/inshua/archive/2008/08/06/2776059.aspx。 这个其实不是做不做的到的问题,而是一种观念的问题。 oo 的意思就是,我必须要按这种方式思考,而 fp 语言在一开始是没有这种要求的。 就像我们写汉字一样,比如 “程”字,你可以把“程”字写的“禾”占大半部分,“呈”占小半部分,这是自由的,笔画规则也是允许的,但是最后写出来发现还是“禾”字小点比较好,写起来也快。 这个比喻里,笔画规则是 fp,而哪部分大哪部分小,这种观念性的东西是 ooa,二者并不矛盾。 至于像 java 这样的 oop 语言,它将 oo 贯彻始终,把类视为顶级公民,在处理过程中把闭包搞成了匿名类,但这并不妨碍我们对它的识别。 类似你的文章中的Javascript Class是可以达到貌似“定义”类的效果。 function A() { this.f1 = f1 this.f2 =f2 } function f1() { } function f2() { } 这种“Hashtable”方式的对象,比“VTable”对象更加灵活。但是,有几个不足。 一是空间浪费。VTable把函数都整理在一起。多个对象共享同一份VTable。而Hashtable则每个对象都需要指向所有function。当然,可以手工模拟VTable的效果,但是代码就太烦琐了。 二是继承实现的便利性。VTable实现继承更加方便。 OO和FP相比。有模型上的不同,观念的不同。 T1的意思是,没有什么难度的区别。只是一开始接收的模型不同。如果大家一开始都用FP,自然会习惯FP模型。 以前看过一篇文章,一个Lisp程序员写的。文中写道,现代学校都教Java,这个语言太普通,太容易,不足以淘汰不适合做程序员的学生。应该一开始就教SICP,就可以淘汰跟不上的学生。SICP的学生确实是叫苦连天的。可见,OO和FP的难度是有区别的。 |
|
返回顶楼 | |
发表时间:2008-08-21
buaawhl 写道 这是Haskekell的类型定义吧。 能不能给一个类型继承的例子。OO多态就是依靠inherit(对于interface叫做implement)来实现的。 所谓的继承不过就是rescursive type罢了 data Window_obj a=Object a|Window a (Object a) |Button a (Window a) |Image_Button a (Button a) class Window_action a where get_type :: a -> String class Image_action a where show_image ::a->IO () instance Window_action Window where get_type (Window a parent)="window" instance Window_action Button where get_type (Button a parent)="Button" ++ get_type(parent) instance Window_action Image_Button where get_type (Image_Button a parent)="Image_Button" ++ get_type(parent) instance Image_action Image_Button where show_image (Image_Button a parent)=...... 没有任何模拟,全部是FP的first class的语言特性. 所以我说,OO(传统OO)的根子完全不在语义语法上,而是计算机模型上. |
|
返回顶楼 | |
发表时间:2008-08-21
inshua 写道 至于像 java 这样的 oop 语言,它将 oo 贯彻始终,把类视为顶级公民,在处理过程中把闭包搞成了匿名类,但这并不妨碍我们对它的识别。 Trustno1 写道 没有任何模拟,全部是FP的first class的语言特性. 所以我说,OO(传统OO)的根子完全不在语义语法上,而是计算机模型上. http://erlang-china.org/misc/commentary-on_a-history-of-erlang.html jackyz 写道 这篇文档所传达的要义(用 Erlang 构造系统的感觉)是:一大堆并行运行着的有限状态机,各处做一做协议验证,彼此松散耦合,通常大部分的有限状态机都处在休眠状态。 |
|
返回顶楼 | |
发表时间:2008-08-21
引用 http://erlang-china.org/misc/commentary-on_a-history-of-erlang.html
jackyz 写道 这篇文档所传达的要义(用 Erlang 构造系统的感觉)是:一大堆并行运行着的有限状态机,各处做一做协议验证,彼此松散耦合,通常大部分的有限状态机都处在休眠状态。 http://www.iteye.com/topic/180281 引用 However, although various kinds of packages or modules are defined for many languages, they are not consequences of a general class declaration as in Simula 67.
The coroutine-like sequencing of Simula has not caught on as a general purpose programming tool. A natural development, however, would have been objects as concurrent processes |
|
返回顶楼 | |
发表时间:2008-08-21
Trustno1 写道 buaawhl 写道 这是Haskekell的类型定义吧。 能不能给一个类型继承的例子。OO多态就是依靠inherit(对于interface叫做implement)来实现的。 所谓的继承不过就是rescursive type罢了 data Window_obj a=Object a|Window a (Object a) |Button a (Window a) |Image_Button a (Button a) class Window_action a where get_type :: a -> String class Image_action a where show_image ::a->IO () instance Window_action Window where get_type (Window a parent)="window" instance Window_action Button where get_type (Button a parent)="Button" ++ get_type(parent) instance Window_action Image_Button where get_type (Image_Button a parent)="Image_Button" ++ get_type(parent) instance Image_action Image_Button where show_image (Image_Button a parent)=...... 没有任何模拟,全部是FP的first class的语言特性. 所以我说,OO(传统OO)的根子完全不在语义语法上,而是计算机模型上. 從 http://inshua.iteye.com/admin/blogs/231336 這個例子足以看出 oop(某些?)和 fp 是同一回事。 我武斷的認為, oo 的出現,是先從軟件工程開始的,和命令式語言合流,則產生 c++,和函數式語言合流,則產生 ocaml 等語言,至於 java 語言,其形象以命令式語言為主,但其精神已經與函數式語言相通。正如命令式語言如引進 lambda 表達式,則可以視同不純粹的函數式語言,而 oop 語言一旦引入匿名類,也有殊途同歸之妙。 但是,目前的這些語言,包括 lisp 等傳統的 fp 語言,從積極方面來看,都是以圖靈機和 lamda 演算為模型,從消極方面來看,都有修改狀態的行為。命令式語言有這個問題,fp 語言同樣也有,lisp 不修改狀態嗎,看過 sicp 就知道,lisp 也同樣修改,雖然作者了解修改狀態帶來的問題,但是他義無反顧的修改了。 要滿足 T1 兄所熱愛的并行的pi演算,確實非函數式語言不可,但前面已經說了,像 java 這樣的語言,完全可以通過匿名類做到和 fp 一樣的效果,所以,可以想象,oo 同樣可以被跑在 erlang 的虛擬機上。 那么 erlang 上面跑 oo 會產生什麽效果呢。 erlang 是以進程為主的語言,但是,1)進程之間要傳遞數據,有時難免要傳遞匿名函數 fun,這種情況在 oo 的誘惑下將會演變為傳遞對象,收到這個數據的目標進程,同時將收到一組方法,目標進程立刻可以知道,怎么操作這個對象,這和 soap 的精神相似,但演算是放在目標進程而不是源進程進行的。2) 很多進程本身可以視為一個對象,erlang 喜歡用的 recv -> new_state 完全可以封裝為一個能發生狀態變化的主動對象。關於這個,可以參考 joe 提出的 !! 運算符。如能視為一個對象,譬如,一個 http 客戶 session 是一個主動對象,屬於 HttpClientSession 類,那么每次創建這個 session 時,就有了一組狀態和函數,用起來也很方便。暫時能想到的就這些,肯定還有很多未知的樂趣。 其實 oo 的教材都是這么說的 軟件 = 對象 + 消息 我第一次看到消息變成了函數調用,還是傻眼了。 |
|
返回顶楼 | |
发表时间:2008-08-21
再舉一個傳遞對象的例子。
如,傳遞一個元組 {lon1 : 113, lon2: 114, lat1 : 22, lat2 : 21},下面是erlang 現在的做法。 p_target ! {lon1 : 113, lon2: 114, lat1 : 22, lat2 : 21} // 很久沒用,語法不對,湊合看看,這個報文表示兩個經緯度坐標 而 oo 化以後,就可以傳遞對象了,則可以寫出如下代碼 p_target ! {lon1 : 113, lon2: 114, lat1 : 22, lat2 : 21, getDistance = function(){...}, getArea = function(){...}} 目標進程可能自己不知道該怎么算兩點之間的距離,但來信已經將計算兩點距離,以及計算兩點組成的矩形之面積的方法都提供了,目標進程根據這個知識可以很輕鬆的計算出距離。 |
|
返回顶楼 | |
发表时间:2008-08-22
引用 要滿足 T1 兄所熱愛的并行的pi演算,確實非函數式語言不可
我并非热爱FP或者Pi演算,而是我只接受经过严格论证后的结果. OO语法自然吗?方便吗? 自然不自然都是相对的,方便不方便都是主观的. 某位仁兄说, Person.writeName()比wirte(char * PersonName) 更自然,于是汇编->C->OO是越来越更加接近人类的认知方式. 在我看来,Person.writeName()并不比Person 'write' "Name" 来的更自然. 后者完全是FP特性构建出来的. FP 构建出语义的自然性绝对是OO无法比拟的,其构建自然语义的方便性直观性也是Ruby,Python这样的动态语言望尘莫及的. 零息票债券合约 zcb :: Date -> Float -> Currency -> Contract -- Zero coupon bond and :: Contract -> Contract -> Contract -- 同时购入两张合约 or :: Contract -> Contract -> Contract -- 在某个时刻购入两张合约中的一张 give :: Contract -> Contract -- 卖出一张合约 at :: Date -> Contract -> Contract -- 在特定时间购入指定的合约 zero :: Contract -- 无效合约 anytime :: Contract -> Contract -- 在合约过期之前可在任何时候履行指定期权 truncate :: Date -> Contract -> Contract -- 在特定日期停止履行合约 一张面值100磅 2010年1月1日到期的零息票债券合约 c1 :: Contract c1 = zcb (date “1 Jan 2010”) 100 Pounds 一张面值100人民币 2010年2月1日到期的零息票债券合约 c2 :: Contract c1 = zcb (date “1 Feb 2010”) 100 RMB 购入一张面值100磅 2010年1月1日到期的零息票债券合约并且售出一张面值100人民币 2010年2月1日到期的零息票债券合约 c4 = c1 `and` give c2 一张欧式期权 european :: Date -> Contract -> Contract european t u = at t (u `or` zero) 一个黄金手铐策略,在2010年1月1日到2011年1月1日中的任何时候,履行一份以100美元购入10股微软股票的合约. golden_handcuff = at (date “1 Jan 2010”) $ anytime $ truncate (date “1 Jan 2011”) $ (zero `or` (scaleK -100 (one Dollar) `and` scaleK 10 (one MSShare)) 这些DSL,全部是函数复合,没有使用任何Tricky特性,类型安全,静态编译.要达到这种效果,Java怎么做?Ruby怎么做? 做到这样自然要花多少精力? 但是这种自然性,便利性无论多么Fancy都无法说服我FP比Java,Ruby更有优势.因为这种自然,便利都是主观的,你看着便利,我看着不便利.对于中国人美国人,Person 'write' "Name"看上去挺便利,但是若是换成日本人Person "Name" write 更便利. 真正能够说服我的是客观的理论推演,和逻辑论证的结果. Why OO Sucks? Because Von Neumann Architecture sucks. |
|
返回顶楼 | |
发表时间:2008-08-22
楼上的挺逗,居然说来说去把OO sucks归根到冯.落衣慢计算机架构sucks.
说了半天,你等于说没说.冯.落衣慢是我们基本的理论前提.是我们现在计算机工业的根本. 照你这么说: 近代经济学一个最基本理论前提就是假设:所有参与到经济行为中的人都是理智的经济人.看看A股,再想想自己,是不是理智的经济人?那这理论前提就是sucks,那现今的经济学全sucks,对不对? 你要说冯.落衣慢架构sucks你先得找一个不sucks的架构给我们看看.我就认为这架构很好 正如我前面说的,我就认为每天拉大便是sucks,因为我觉得如果能进化出不拉大便的能力当然更牛B.说说你的计算机架构. |
|
返回顶楼 | |
发表时间:2008-08-22
Trustno1 写道 引用 要滿足 T1 兄所熱愛的并行的pi演算,確實非函數式語言不可
我并非热爱FP或者Pi演算,而是我只接受经过严格论证后的结果. OO语法自然吗?方便吗? 自然不自然都是相对的,方便不方便都是主观的. 某位仁兄说, Person.writeName()比wirte(char * PersonName) 更自然,于是汇编->C->OO是越来越更加接近人类的认知方式. 在我看来,Person.writeName()并不比Person 'write' "Name" 来的更自然. 后者完全是FP特性构建出来的. FP 构建出语义的自然性绝对是OO无法比拟的,其构建自然语义的方便性直观性也是Ruby,Python这样的动态语言望尘莫及的. 这也只是表达方式而已,oo 不是说非得用 o.ma 不可,虽然现在的 oop 语言有这个习俗,但这和oo的本质实际上不相干。你能说你脑海里没有 Person 这个观念? fp 语言也有很多,也不是每种 fp 语言都支持你的写法,比如你下面的写法,充满了连绵不断的符号,你可能感觉挺爽的,但是别人呢? 又比如你下面的写法,换成 lisp 来写,或者换成 js 这样的 fp 语言来写,能收到同样的效果吗?不能。 我所解释的 fp 构造对象的方式,是按 sicp 里 cons 的定义构造的,除了 fp 的东西没有牵涉到其它函数以外的知识,是纯粹的 fp 的 oo,没有什么蹩脚的。 oop 语言既然构造闭包,自然能演绎出 curying,monad 等等 fp 的基本特性,所以你那串以为非 fp 莫属的写法在 oop 语言是完全可以实现的,只不过那个语言未必是 java。这个命题是毫无疑问是符合逻辑的。这个推理按形式逻辑是充分前提的推理,按因明是宗因喻齐全的比量,如果你认为这个推理有哪一阶段不符合逻辑,敬请提出。 Trustno1 写道 真正能够说服我的是客观的理论推演,和逻辑论证的结果. Why OO Sucks? Because Von Neumann Architecture sucks. 我想你可能需要换个视角来看,从数学来看,函数是完备的,但是从物理来看呢? 打一个不恰当的比喻,函数揭示了事物的波本质,而 oo 揭示了事物的粒子特性,物理特性,以及化学特性。 我们的确在用数学解释世界,但你能证明数学为何能解释已知未知的一切现实世界吗? |
|
返回顶楼 | |
发表时间:2008-08-22
terranhao 写道 楼上的挺逗,居然说来说去把OO sucks归根到冯.落衣慢计算机架构sucks.
说了半天,你等于说没说.冯.落衣慢是我们基本的理论前提.是我们现在计算机工业的根本. 照你这么说: 近代经济学一个最基本理论前提就是假设:所有参与到经济行为中的人都是理智的经济人.看看A股,再想想自己,是不是理智的经济人?那这理论前提就是sucks,那现今的经济学全sucks,对不对? 你要说冯.落衣慢架构sucks你先得找一个不sucks的架构给我们看看.我就认为这架构很好 正如我前面说的,我就认为每天拉大便是sucks,因为我觉得如果能进化出不拉大便的能力当然更牛B.说说你的计算机架构. 不是,冯诺依曼模型只是一种模型而已,做 dsp 的还用哈佛模型。T1 非常热爱 PI 演算(注:因为一大批符合逻辑的论文),但其实 oo 和 pi 演算并没有本质的冲突,只要把 object 看做一个闭包就完全理顺了。 |
|
返回顶楼 | |