1. 程式人生 > 其它 >名詞王國裡的死刑(轉載)

名詞王國裡的死刑(轉載)

發現一篇關於函數語言程式設計的文章和吐槽Java完全面對物件(名詞)設計的文章,很有意思。就轉載了過來。

翻譯自Steve Yegge的大作《Execution in the Kingdom of Nouns》原文在 這裡

翻譯正文

Hello,world!今天我給大家講一個關於Java魔鬼國王和他在全國範圍內驅逐動詞的故事。

注意:這個故事並沒有什麼圓滿結局。如果你心靈脆弱或者吹毛求疵的話,這個故事不適合你。如果你易於動怒或喜歡在別人的部落格上妄加評論, 那麼請立即停止閱讀。

在我們開始這個故事之前,先讓我們熟悉一下背景:

溢位的垃圾

所有使用Java的人都喜歡“用例”,所以讓我們以一個用例開始吧:倒垃圾。就像這樣:“Johnny,快去倒垃圾,他都快溢位來了!”

如何表達倒垃圾這一活動呢?如果你是一個正常說英語的人,你可以粗略地用以下幾句話來描述它

在水池下取出垃圾袋



帶著垃圾袋去車庫



把它扔到垃圾桶裡



走回來



洗手



坐回沙發上



繼續玩你的電視遊戲(或者幹其他的事)

即使你不用英語思考,你也會想象出一系列類似的動作。不考慮你選擇的語言,或者採取的具體步驟,取決於你採取的行動,倒垃圾是一系列終止於垃圾在外面,你回到屋子裡的動作。

我們的思想充斥著各種或勇敢的,或暴躁的,或激昂的動作。我們生活,我們呼吸,我們走路,我們談話,我們笑,我們哭,我們希望,我們害怕,我們吃,我們喝, 我們走,我們聽,我們倒垃圾。我們能自由地“做”和“行動”。假如我們只是石頭,生活沒準還算好,但是我們不會自由。因為我們可以“做”事,所以才會自由。

我們的生活也同時充斥著各種“名詞”。我們吃“名詞”(食物),我們從商店買“名詞”(商品),我們坐在“名詞”(凳子)上。 “名詞”(石頭)可能會忽然砸到你頭上,在你的“名詞”(頭)上弄一個“名詞”(大包)。名詞即事物,想想沒有了事物我們會怎樣?但他們僅僅只是事物,比如: 意味著結束或者結束本身,或者一些貴重物品,或者我們周圍經常看到的事物的名字。這是一座建築,那是一個石頭。任何一個小孩子都能指出名詞,僅此而已。發生在名詞身上的 “變化”才是最有趣的事情。

變化需要動作。動作是生活的調料。動作甚至給了調料以調料!畢竟除非你“吃”它,你是不會感到香這種味道的。名詞也許無處不在,但是生活一直在變並一直有趣的功勞還是在於動詞、

當然,除了名詞和動詞,我們還有形容詞,介詞,代詞,冠詞,連詞,語氣詞,和許許多多其他讓我們構造有趣語言的詞彙。它們都在語言中扮演著自己的角色,而且每一個都很重要。 如果它們哪一個不存在了的話,那是挺遺憾的事情。

那麼,如果有一天我們不再用動詞了,你是不是感到很奇怪呢?

在下面我要給大家講的故事裡,這件事情真的發生了……

名詞王國

在Java王國中,國王Java以鐵腕統治著他的國家,而他子民的思考方式也並不和你我一樣。在這裡,你可以看到,名詞是十分重要的並直接服從國王的命令。 名詞是最重要的居民,它們身穿豔麗的服裝顯得高貴而優雅,而這些衣服是由形容詞提供的。而形容詞哪,也很滿意它們的生活,當然,他們不可能像名詞那麼高貴, 不過相比於動詞來講卻幸運得很多。

因為,動詞在Java王國裡的日子,相當,相當的糟糕。

奉國王Java的法令,動詞是隸屬於名詞的,但他們不僅僅是寵物而已。或者說連寵物都不是,在整個國家,動詞負擔起所有的勞力工作。實際上,他們是王國的奴隸,至少是 農奴或者契約奴之類的。Java王國的居民對自己的生活還是比較滿意的,他們從來沒有想到會發生什麼變化。

動詞負責王國裡的所有工作,但是仍然獲取不到任何尊重,甚至都不允許單獨出來。如果一個名詞被發現在公共場合出現,它會立即被名詞逮捕。

當然“逮捕”也是一個動詞,他也從不被允許單獨行動;你必須創造一個“動詞逮捕著”來協助逮捕。但是“創造”和“協助”哪?這樣的話,“創造者”和“協助者”也各自在這個工作上 伴隨“創造”和“協助”起到了重要的作用。

國王Java,在他的上帝Sun(現在是Oracle了吧...[譯者注])的指引下,時不時地威脅要將所有動詞驅逐出王國。如果那一天到來了,他們當然需要至少一個動詞來做 各種工作,而從國王殘忍的幽默感上猜測,這個動詞很可能就是“執行”。

動詞“執行”(execute),和它的親戚“執行”,“開始”,“走你”,“做”,“就這樣做”或者相似的什麼詞可以通過找到合適的“執行者”來替代任何其他的動詞。想等(wait)一下? Waiter.execute().刷(brush)牙(teeth)?ToothBrusher(myTeeth).go().扔(take out)垃圾(garbage)?TrashDisposalPlanExecutor.doIt()。沒有任何 一個動詞是安全的,一切動詞都會被執行的名詞而取代。

在這種精神更加氾濫的角落,名詞已經把動詞驅逐乾淨。不仔細看的話,你會覺得仍然有動詞存在,比如耕種或倒茶壺,但是一旦仔細觀察,真相便浮出了水面:名詞可以隨意 命名緊跟在它們後面的動詞“執行”,而不改變自身的角色。所以,當你看到“耕地者”在“耕地”,“倒茶壺者”在“倒”或者說“註冊管理者”在“註冊”,你真正看到的是魔鬼國王Java的 “執行者”大軍,只不過他們披著所有者的外衣而已。

在其他王國裡的動詞

在其他程式語言的王國中,倒垃圾是一件很直白的事情,和我們用英語表述的十分相似。在Java王國中,資料實體是名詞而函式是動詞,而在其他王國中卻不然:王國的居民 是混在一起的,而且在能順利完成工作的前提下,只要他們願意,既可以是名詞也可以是動詞。

比如在附近的C的領域,JavaScript的地盤,Perl的地盤和Ruby的地盤,他們可能會把倒垃圾這件事分解成一系列的動作(或者叫做動詞或者函式)。如果他們將這些 動作以適當的順序應用於適當的事物(拿垃圾,把它帶出去,扔到垃圾桶裡等等),倒垃圾的任務就圓滿成功了。在這個過程中根本不需要執行者或其他的伴隨者這出現。

在這些王國裡,真的沒有必要創造這麼多的包裹器來包裹動詞。他們沒有“垃圾傾倒策略”之類的名詞,或者“垃圾傾倒地點定位者”來只是你倒垃圾的路徑,也沒有“倒完垃圾後的回撥”來保證你 倒垃圾後回到自己的沙發上。他們只是寫一些動詞來操作名詞,並建立一個主要的名詞,例如,提出垃圾(take_out_garbage())並把一些需要做的子動作放在裡面。

在這些王國中,當需求提升的時候,也通常有一種機制來生成比較重要的名詞。如果這些精明的創造者創造出了一個全新的名詞,比如房子,馬車,或者耕起地來比人還快的機器, 他們會被給予一個統一的概念:類。而人們會給類一個名稱,一個描述,一些狀態和一些操作建議。

這些王國與Java的不同之處在於,動詞是允許單獨出現的,你沒必要創造新的名詞去束縛他們。

Java王國的人一種輕視的態度看待他們的鄰居;而這也是程式諸王國的現狀。

如果你挖個足夠深的洞...

在世界的另一邊,有一篇貧瘠的居住地。在那裡,動詞居民的地位十分之高。這就是函式式王國,包括Haskellia,Ocamlica,Schemeria和一些其它的國家。 因為附近的國家很少,他們幾乎不與Java王國何其附近的國家有接觸。也正因為這樣,函式式諸國們相互輕視,並有事沒事的時候打一仗以排遣寂寞。

在函式式王國裡,名詞和動詞一般被看做同樣等級的居民。但是,名詞,對是名詞,基本上整天無所事事。他們的出現在做事或者執行任務的時候並沒有多大意義,因為 活躍的動詞們基本把能做的事情都做了。這裡也沒有什麼奇怪的法律說要創造各種“幫助者”來幫助動詞做事,因此在這些王國中,名詞的數量和實際上存在事物的數量是相同的。

這樣做的結果是,動詞在這片土地上為所欲為(請原諒我的用詞)。如果你是一個外來人,你很容易產生名詞(函式)是這裡最重要的居民的印象。順便提一句, 這也是為什麼這裡被叫做函式式諸國還不是事物諸國的原因。

在最為遙遠的地方,遠離函式式諸國,存在著一塊傳說中的土地,“Lamda the Ultimate”(終極lamda?霸氣~[譯者注])。傳說中在那裡,沒有名詞,只有動詞。 那裡有事物,但事物由動片語成。如果傳說不虛,甚至數字,那裡最為流行的貨幣,也是動詞!數字0被表示為lamda(),數字1是lamda(lamda()),2是lamda(lamda(lamda())),以此類推。

在這片神奇的土地上,一切事物,別管你是名詞,動詞,還是其他什麼,都是由最基本的動詞lamda組成的。

老實說,Java王國中幸福生活著的居民並沒有意識到另外一個世界的存在。你能想象得知此事之後的文化震動麼?他們可能會發明一個新的名詞(比如“憎惡”)來表達自己新的感受。

Java王國中的居民真的快樂麼?

你可能覺得Java王國中的生活有點奇怪,如果糟糕的話還效率還會變得十分低下。不過,你能從一個地方的童謠中看出他們的幸福程度,而Java王國的童謠,是一群古怪的詩。 比如,這裡的兒童經常朗誦的寓言: (這就不翻了[譯者注])

    For the lack of a nail,



        throw new HorseshoeNailNotFoundException("no nails!");



 



    For the lack of a horseshoe,



        EquestrianDoctor.getLocalInstance().getHorseDispatcher().shoot();



 



    For the lack of a horse,



        RidersGuild.getRiderNotificationSubscriberList().getBroadcaster().run(



          new BroadcastMessage(StableFactory.getNullHorseInstance()));



 



    For the lack of a rider,



        MessageDeliverySubsystem.getLogger().logDeliveryFailure(



          MessageFactory.getAbstractMessageInstance(



            new MessageMedium(MessageType.VERBAL),



            new MessageTransport(MessageTransportType.MOUNTED_RIDER),



            new MessageSessionDestination(BattleManager.getRoutingInfo(



                                            BattleLocation.NEAREST))),



          MessageFailureReasonCode.UNKNOWN_RIDER_FAILURE);



 



    For the lack of a message,



        ((BattleNotificationSender)



          BattleResourceMediator.getMediatorInstance().getResource(



            BattleParticipant.PROXY_PARTICIPANT,



            BattleResource.BATTLE_NOTIFICATION_SENDER)).sendNotification(



              ((BattleNotificationBuilder)



                (BattleResourceMediator.getMediatorInstance().getResource(



                BattleOrganizer.getBattleParticipant(Battle.Participant.GOOD_GUYS),



                BattleResource.BATTLE_NOTIFICATION_BUILDER))).buildNotification(



                  BattleOrganizer.getBattleState(BattleResult.BATTLE_LOST),



                  BattleManager.getChainOfCommand().getCommandChainNotifier()));



 



    For the lack of a battle,



        try {



            synchronized(BattleInformationRouterLock.getLockInstance()) {



              BattleInformationRouterLock.getLockInstance().wait();



            }



        } catch (InterruptedException ix) {



          if (BattleSessionManager.getBattleStatus(



               BattleResource.getLocalizedBattleResource(Locale.getDefault()),



               BattleContext.createContext(



                 Kingdom.getMasterBattleCoordinatorInstance(



                   new TweedleBeetlePuddlePaddleBattle()).populate(



                     RegionManager.getArmpitProvince(Armpit.LEFTMOST)))) ==



              BattleStatus.LOST) {



            if (LOGGER.isLoggable(Level.TOTALLY_SCREWED)) {



              LOGGER.logScrewage(BattleLogger.createBattleLogMessage(



                BattleStatusFormatter.format(BattleStatus.LOST_WAR,



                                             Locale.getDefault())));



            }



          }



        }



 



    For the lack of a war,



        new ServiceExecutionJoinPoint(



          DistributedQueryAnalyzer.forwardQueryResult(



            NotificationSchemaManager.getAbstractSchemaMapper(



              new PublishSubscribeNotificationSchema()).getSchemaProxy().



                executePublishSubscribeQueryPlan(



                  NotificationSchema.ALERT,



                  new NotificationSchemaPriority(SchemaPriority.MAX_PRIORITY),



                  new PublisherMessage(MessageFactory.getAbstractMessage(



                    MessageType.WRITTEN,



                    new MessageTransport(MessageTransportType.WOUNDED_SURVIVOR),



                    new MessageSessionDestination(



                      DestinationManager.getNullDestinationForQueryPlan()))),



                  DistributedWarMachine.getPartyRoleManager().getRegisteredParties(



                    PartyRoleManager.PARTY_KING ||



                    PartyRoleManager.PARTY_GENERAL ||



                    PartyRoleManager.PARTY_AMBASSADOR)).getQueryResult(),



            PriorityMessageDispatcher.getPriorityDispatchInstance())).



          waitForService();



 



    All for the lack of a horseshoe nail.

直到今天,這仍然是美好的建議。

儘管在Java王國的敘述方式和本.富蘭克林的原作大有不同,但是這裡的居民覺得他們的重新編排還是有一種不同的魅力在裡面。

而最大的魅力在於“架構”,是所有人都能看見的。架構被國王Java授予了之高無上的地位,因為,架構全部是由名詞構成的。正如我們所知的,在Java王國,名詞即事物,事物 的榮耀高於一切的動詞。架構由無數事物構成:你可以看或觸控的事物,給你留下壯觀印象的事物,用棍子刮擦發出美妙聲音的事物。國王Java,十分喜歡刮擦的噪音; 每當他新換車伕的時候,踢輪子發出的美妙聲音讓他覺得很滿意。不管上面的故事有什麼瑕疵,“事物”總是不缺少的。

作為人類,我們的第一本能總是尋找由各宗物體構成的庇護。庇護越堅固,我們感覺越安全。在Java王國,有很過堅固的東西讓居民們感到安心。他們感慨如此龐大的架構 建造之神奇並認為它是“最為堅固的設計”。而且每當結構變化時,他們就越堅信這點。接著,架構的力量也變得強的令人生畏以至於沒有人認為可以摧毀他。

除了堅固的架構之外,在Java王國中的所有東西很有調理地組織著:你會發現任何名詞都會呆在適當的地方。這裡每個故事都有一個固定的模式:例項構造在故事的表述中佔了主要的篇幅, 因為每個抽象都會有一個管理者(Manager),而且每個管理者都有一個run()方法。Java居民們覺得他們可以用這種模型表述任何事情。這是一種“名詞計算”,只要你願意, 它可以滿足任何抽象,任何計算。你需要的僅僅是足夠的名詞,名詞的構造器,獲取器方法,和重要的execute()函式來實現你的計劃。

Java王國的居民活的不僅僅是幸福,簡直是迸發出強烈的自豪感。

StateManager.getConsiderationSetter("Noun Oriented Thinking", State.HARMFUL).run()

或者,正如外面的世界所說,“面向名詞的思考是有害的”

面向物件的程式設計把名詞放到首位,但是我們為什麼非得把名詞捧上神壇以至於讓語句變的如此囉嗦哪? 為什麼一種語句成分的低位非得高於另外一種?這並不是好像面向物件的程式設計突然使得動詞的低位降低,正如我們認為的那樣。 這是一種奇怪的認識的扭曲。正如我的朋友 Jacob Gabrielso一次說到,提倡面向物件的程式設計好比提倡面向褲子的穿衣方式。

Java的靜態型別系統,像起他任何類似的語言一樣,有著共同的問題。但是過分強調面向名詞的程式設計思想給人帶來很大的困擾。 任何型別系統都會要求你重新梳理思路來配合它,但是清除獨立的動詞看起來十分不合情理。

C++並沒有這個問題。因為C++作為C語言的超集允許你定義單獨的函式。 此外,C++提供了獨立的名稱空間的概念。Java的類承載了太多的內容:名稱空間,使用者自定義型別,句法委託機制,可見性和作用域機制,等等。

不要誤解了我的意思。我並沒有說C++“好”,我只是讚美它至少相比於Java來講靈活的型別系統。C++出現問題會讓聽眾抓狂並且想殺了你 (比如,意想不到的段錯誤和其他難以發現的隱患)。並且在C++你很難找到一個能描述你的想法的咒語。 但是它靈活地可表述的思想的範圍卻遠遠超出了Java。因為C++提供給你了動詞,誰想用一個沒有動詞的語言說話哪?

類是Java中唯一提供的建模的工具。所以當一個新的想法出現在你腦海的時候,你不得不重塑它,包裝它,甚至弄碎它直到它變成一個名詞, 即使它開始是一個動作,過程,或者任何其他不是“物”的概念。

我似乎回到了8,9年前一幫搞Perl的傢伙對我說的:“夥計,並不是所有的東西都是物件的。”

很奇怪,Java似乎是主流面嚮物件語言中唯一一個完全以名詞為中心的語言。 在Python或者Ruby中,你不會找到AbstractProxyMediator,NotificationStrategyFactory或者其他類似的東西。 為什麼在Java中它們滿地都是?我敢打賭這是原因出在了動詞的身上。Python,Ruby,JavaScript,Perl當然,還有所有的函數語言程式設計語言允許你宣告並傳遞函式而不用用類包裝它。

很顯然,動態型別語言的使用更容易;你可以僅僅傳遞一個引用給函式,函式可以用名字獲取它,而函式的呼叫者僅僅用合適的引數呼叫函式並正確地使用返回的值就可以了。

但是很多靜態型別的語言同樣也有第一類的函式。 這包括固定型別的語言比如C和C++,還有型別自動推斷的語言比如Haskell和ML。 這些語言僅僅需要一些語法來建立,傳遞和呼叫函式的內容就可以了。

Java沒有理由不簡單地新增第一類函式並最終實現一個成熟的,沒有扭曲的可以讓人自由運用動詞來實現他們想法的世界。 實際上,有一個基於JVM叫做 The Nice programming language 的語言實現了一個非常類似Java的語法,幷包含了一個非常具有表現力的實現了使用動詞方式:獨立函式。 而Java強制你用Callback,Ruunable或其他匿名介面來包裝它為一個類以便於呼叫。

Sun公司甚至沒有打破他們一切函式都必須被類擁有的信條。任何匿名的函式都會具有一個隱式的this指標指向定義它的類;問題解決了。

我不知道為什麼Sun公司堅持Java矗立在名詞王國。我懷疑這是低估了他們的民眾;他們添加了泛型,一個更加複雜的概念,所以他們不再關心如何保持他們語法的簡練。 並且新增動詞並不是一件壞事,這是因為Java現今所建立的:為一個Java程式設計師提供工具讓他們按自己的想法程式設計更有意義。

我真心希望Java能修復這個缺陷,以便我可以把垃圾帶出去並回來玩遊戲或者一切當時在做的事情。