2011/03/31

讀後想法:孤劍不折(柴田鍊三郎)與祕劍.柳生連也齋(五味康祐)

這類小說被稱為「時代小說」或「劍豪小說」,時間通常設定在戰國、江戶幕府,在那樣子的大時代背景底下,故事圍繞在擊劍的藝術打轉,主角通常是劍豪,追求劍的極詣。

我看了下面兩本,很少,寫寫這篇感想。其實已經看完很久了,居然拖到現在。也不想再看其他同類型的小說了,又是三分鐘熱度的表現,哈哈。

孤劍不折(柴田鍊三郎)


祕劍.柳生連也齋(五味康祐)


因為設定在歷史朝代中,書中多半有真實歷史的根據,幾分實幾分虛就看作者的需求了,或許弄出個國家滅亡殘存的公主由主角來保護,或者在有實際考證之中插入想像的外傳,譬如說,孤劍不折的主角,神子上源四郎,其受業師傅正是小野忠明,生存年代為1569-1628。

下圖在信長之野望-革新裡,小野忠明的能力值。這類劍豪角色多半被設定為統率很低(帶低打仗能力差),武勇很高(使出絕招時很厲害),同類型的角色還包括:宮本武藏、佐佐木小次郎、上泉信綱、柳生宗嚴、丸目長惠等。


書中最吸引我注意的,大概就是劍術(刀術)與戰鬥的描寫,譬如說:
柳生流有一招奧義叫「月陰」,那是從日月陰陽中,選定月與陰的劍法奧義。月有形,照明暗夜;陰無形,代表黑暗。正因為有月光,才看得見陰。例如在暗夜決戰時,看不見敵人的身影,也看不見自己的影子。這樣要以什麼作為對象呢?敵我雙方都像在黑暗中探物般,揮刀掃動地面。看出對手以長劍探尋時的光影,展開攻擊。

當然了,招式是劍尖朝下的下段招式,當敵人看準我方小腿出劍時,配合其劍身的光芒,接連使出反照出我方劍光的快劍,此稱之為「月陰」。

月陰又轉化出 「山陰」這項奧義。這是陰陽表裡,對敵人的變化能應付自如的一種變化。山陰又轉化出宛如烈風吹襲海面,激起波濤的「浦波」這招秘技。



當我初看時,有一種新鮮感,跟熟知的金庸古龍等武俠小說的描寫不太一樣,讓我眼睛一亮,書中還有很多這類劍術招式奧義的描寫,當然,老梗不能一直用,作者也會竭盡腦汁想出天馬行空的招式,配合日落、配合心氣神等等,最後往往達到劍人合一的境界,劍招就代表使劍的人,劍手是什麼樣的人才能使出那樣的劍招。

書中也會有描寫時代背景、人物故事、情節鋪陳等,雖也不錯,但我看過便罷,或許是沒興趣吧,也許是無法領略其筆法吧,總之,並不會特別記得些什麼。

我是先看孤劍不折,這是一本四百多頁的故事,覺得很不錯,所以又買了祕劍.柳生連也齋,這裡面是11個短篇故事集結成書的,有喜歡的也有看的昏昏沉沉的。後來就提不興趣看其他本了,感覺興致已盡,況且,書架上還有好幾本小說沒看咧,orz。

我對這種日本劍道會產生些許的興趣想多了解一點,大概是來自玩太閣立志傳跟看日劇鹿男吧。

日劇鹿男,堀田取得大和杯優勝時的場景。


太閣立志傳是個靈活度很高、遊樂性很強的遊戲,從早期你只能當武將,到後來你可以當劍豪、忍者、商人等等。下圖為比劍的畫面,以卡片來戰鬥,修煉後可取得秘技奧義等強力卡片使出招式。

一個人格格不入,格格不入的一個人。

PS 這篇部落格不過是些無病呻吟,沒什麼好看的。

人生啊,總會浮現許許多多的問題,有些簡單有些複雜,有些無限多解有些無解,就算自以為找到了,免不了一定會有是見樹還是林的疑惑,又再次陷入重複循環的陷阱裡,如此一而再再而三,不是發瘋就是放棄。

此時,就算是走完長長的哲學之道,也只會腳酸,腦子也不會更清楚。


人啊(我是說我啦),就算在一群人之中,也會突然恍神,魂魄不知道飄到哪兒去了,哇哈哈。

霸王傳說第十八卷中巽凱與獵火的對話。


有人說,就算把全世界的財富集合起來然後平均分配給所有人,不出十年二十年,財富又會回復到原本的分佈狀況。有朋友的人去到哪都交得到朋友,另一種人的朋友數目只會越來越少。所以說,個性決定命運,我越來越相信了啦。

聽著陳綺貞的歌,旅行的意義,我們知道,有些話真的不能也不會被說出來。


You can't find it, create it. 這是我在澳洲旅行時看到最感動的話,尋找只是過程,創造成為結果。


哈哈,不知所云,睡吧睡吧,田園將蕪胡不歸,月明星稀胡不睡。

2011/03/30

翻譯:多型不行時(When Polymorphism Fails )by Steve Yegge

文章:When Polymorphism Fails(多型不行時)
日期:2004.08.25
作者:Steve Yegge
作者的部落格(2006至今):Stevey's Blog Rants
作者舊的文章(2004與2005):Stevey's Drunken Blog Rants

作者簡介:
目前任職於Google,之前曾任職於Geoworks與Amazon。程式語言生涯中有過兩次非常關鍵性的轉換,一次是組合語言,一次是Java 跟Perl,因為發現解決語言本身設計帶來的問題所花的時間,竟然比真正用在開發軟體系統的時間還多。其文章以長度聞名,長到應該稱為論文而非部落格,兼帶詼諧筆風,發表頻率大約一個月一到兩篇,作者總是說這些是在凌晨三罐啤酒下肚後的誇誇其談,但每一篇都是經過長時間醞釀,內容充實有見地的傑作。

獨立以Java/JPyton開發多人線上遊戲Wyvern,可讓玩家自行創建擴充遊戲內容。其工作團隊將Rails移植到Rhino上,Rhino是運作於JVM平台上的JavaScript引擎,Rails(Ruby on Rails)為一套受到廣泛喜愛使用的網站開發模組;為Emacs撰寫完整的JavaScript環境,期望在Emacs上可以有一套 JavaScript IDE,以及將來可用JavaScript而非elisp來開發Emacs extensions。


多型不行時(When Polymorphism Fails )


每個愛好OOP(object-oriented programming)的人順理成章地也會是多型(polymorphism)的狂熱份子,有很多本來可以更好的書籍(譬如Fowler那本講重構(refactoring)的),竭盡所能地傳達出一種信念:如果你用了執行期間型別檢查(runtime type checking),也就是Java的"instanceof"運算子,那麼你大概是個壞胚子,是那種會手拿switch恐嚇小孩子的邪惡角色。

總括來說,若是用上了"instanceof",這通常就表示程式的OO作的不好,這點我是同意的,那表示設計的技巧不足,兩相比較起來,應該要盡量使用多型,而不是執行期間型別檢查,寫出來的程式碼會比較乾淨比較容易維護,然而,我認為,至少存在一種狀況,這種狀況很常見到處都有,有資格稱為一個範式,在這種情況下你根本無法使用多型,如果你知道怎麼用,拜託告訴我,我很渴望知道,但我認為不太可能,至少在Java或C++這種靜態語言裡是不可能的。


多型的定義

若是你不是很熟悉OOP的術語,讓我解釋一下,多型是個矯揉造作的詞彙,它的概念其實就是延遲連結(late binding),而延遲連結這個詞彙也很矯揉造作(繼續往下看你會知道其中的奧妙),它的意思是,把找出哪個方法(method)要被呼叫的決定延遲到執行期間才作,到那時才判斷被呼叫的對象目標是不是能回應訊息。

以效能為優先考量的語言,譬如C++、Java、OCaml,方法(methods)會被賦予數字編號,每個類別都有一張表記錄著有哪些方法,在執行時會掃描這張表找出被呼叫的方法;而另外一方傾向於在執行期間時能夠擁有較大彈性的語言陣營,其找出方法的手段,通常是對方法的名字作雜湊(hashing)來判斷,除此之外,這兩種方式其實可看做是同等的。

光有虛擬方法(virtual methods)並不會帶來多型,多型冒出來的條件是:當你有好幾個子類別(subclass)繼承自某一個類別,每一個子類別都實作自己的多型方法,而且各自處理方式皆不相同。舉一個教科書上用到爛的例子,如果你去動物園,你會看到,動物們處理createBadSmell()訊息的方法都不一樣,嗯,或許從某些觀點來看會有共通極為類似之處,我猜啊,做那回事時的聲音大小算是個重點,我還是無法判斷出,到底是河馬還是長頸鹿的表現能力比較好,不過,有興趣的話你可以在過段時間後再來問問我。


多型大搖大擺地炫耀著

舉個實際一點的多型範例吧,讓我們來看看一個面試中會問的經典評估問題,就我所知,這是由Ron Braunstein帶進Amazon的,這問題的內涵相當豐富,企圖要探測出求職受試者是否擁有各種重要的技能:OOP設計、遞迴、二元樹、多型與執行期間型別檢查、一般撰碼技巧、以及(如果你要搞成這麼難的話)語法解析理論(parsing theory)。

進行在某個時間點,求職者應該能夠領悟到,可以把數學運算式以二元樹表示出來,在此假設只有二元運算子的情況,如"+"、"-"、"*"、"/",樹葉節點皆為數字,內部節點皆為運算子,想求出運算式的值就表示要把這棵樹走過一遍,如果受試者想不到這點,你可以適當地引導他們走到這一步,或是,若有必要的話,直接告訴他們也行。

即使你直接提示他們,這仍然會是個有趣的問題。

這問題的前半部分,某些人(為了人身安全我不敢點名,但他們的名字字首是Willie Lewis)覺得"如果你叫自己是個程式開發人員而且想在Amazon工作的話,這是一定要會的啦",但事實上是有些困難的,問題的前半部分是:你如何把一個數學運算式(例如在一個字串裡),例如是"2 + (2)",轉換成一棵運算樹,在我們的ADJ挑戰賽中應該有出現過這一題。

問題的後半部分是:假設這是個兩人專案,你的夥伴,讓我們叫他"Willie",負責把字串轉成樹,你負責簡單的部份:決定Willie應該用什麼類別把樹建構出來。你可以挑任何一種語言來用,但一定要確實挑出一種來,要不然Willie會用組合語言寫好交給你,要是不幸遇到他心情不好,那麼會更慘,他會用那種處理器已經停產的組合語言寫給你。

有很多面試求職者被這梗擊中爆笑不已喔,驚訝吧。

我不會給出解答,不過,標準的壞答案是,使用switch或case的語法(或是老派一點,一連串的if);稍微好一點點的答案是,使用儲存函式指標的表格;而大概稱得上最佳的解答是,使用多型。我鼓勵你做做看這題,很有趣喔!

諷刺的是(底下你就會看到),如果你想要打造一套可擴充有延伸性的系統,使用多型是相當理想的解答,如果你想要在系統內加入新的函式,而不想重新編譯整個系統──特別是,不想在那個有500個case的巨大分支指令裡加入更多的case,那麼,你就會想要使用多型。


用三種多型形式的歡呼來為多型喝采

所以,多型,講了這麼多,看起來還滿有用的。至今,多型最有用的地方是,呃,多型print。如果你用過Java、Python、Ruby或其他"真正"的OO語言,那麼多型print對你來說不是什麼新鮮事,你下命令叫物件把自己印出來,天呀,就印出來了,每個物件會印出內部狀態,恰恰好是你所需要知道的,在除錯、追蹤、記錄時非常有用,甚至在製作說明文件時也很有用。

如果你用的是有著扭曲OO外表的語言,例如C++或Perl這種強加裝上物件導向配件的語言,就好像是把一對價值美金2500的輪胎邊框裝在1978年的速霸陸老舊車款上,那麼,你能用的就是除錯器,或是Data::Dumper,或是類似的東西。哈,可憐喔,你啊!

(反問句:為什麼我們選擇使用C++與Perl呢?此兩者為世上最爛的語言是也!照同一標準的話,也可以用Pascal和Cobol啊,哭吧,大聲一點。)

順便說一下,最近我都沒提到OCaml,主要原因就是多型print,OCaml沒有提供多型print,原因我還沒完全搞懂,但大概落在"設計者的嚴重精神失常"那附近,因此,你沒辦法為了除錯而隨便叫一個物件在主控台上print出來;我希望他們這麼設計是有其必須性的,譬如為了能讓OCaml達到那擊敗C++效能表現的神奇傳說,若非如此,那就好像在使用便利性上打了一巴掌污辱人嘛,不過至少OCaml有支能夠穿越時空往回走的除錯器,你必定會需要它的。

總之!我們喜歡多型,多型就是微控管理的反面,你叫物件做事情,無需告訴他們要怎麼做,而他們就會忠實無誤地到網路看上整天的Strong Bad影片,嘿,那群笨笨的物件啊!愛死他們了。

可是,可是,多型啊,就好像所有的正義角色,擁有黑暗的一面,就多型這個案例來說,並不像,嗯,安納金天行者的黑暗面那麼黑,不過,不管怎麼說,黑暗面就是黑暗面。


多型的矛盾

要在程式碼裡使用多型,有個不明顯但非常要緊的條件:在之後你還能增加東西進去。至少,對靜態語言來說,例如Java與C++,如果你增加了一個多型方法,你必須重新編譯那些實作出方法的類別,也就是說,你需要擁有原始程式碼,並且能夠進行修改。

在我的能力範圍內,至少可以說出,的確有某一類系統是做不到這件事的,那就是:可擴充系統(extensible systems)。

讓我們假定,你正在打造一套嶄新的系統,允許使用者自行加進程式碼,這可不是件簡單的任務,有很多理由要考量,包括保密安全性、緒程安全、以及其他許許多多的地方,不過這種系統是存在的!譬如說,有些線上遊戲可以讓玩家放進他們自己寫的程式碼,毋須存取原先的遊戲原始碼程式,大部分的多人線上遊戲都朝著這個方向前進──管理階層意識到,使用者想要而且有能力創造出好的內容出來,所以讓遊戲把APIs公開出來,讓玩家能夠打造他們自己的怪物、法術等等,藉此擴充延伸遊戲系統。

嗯,我聽到某種聲音告訴我說,網站服務(web services)也走向類似的道路。

在任何時候你想打造出這種可讓使用者進行擴充的系統,就需要花費三倍多的心力,多出來的兩倍工作量在於,把你內部APIs與類別安排整理好,使得它們是可以被使用者所修改運用的。

Java的Swing就是個很好的範例,打造可擴充系統時,你就會跑進創造者矛盾(Inventor's Paradox)的弔詭中,你可以上網找找看,不過它的中心大意就是,你沒辦法事先預想出,你的使用者想要對系統的哪些部分進行修改。你可以把限制一直往外推──就算是你把系統裡的每一行程式碼都搞成虛擬函式並公開出去──即便如此,你的使用者最終仍然會跑到某個他們沒辦法客製修改的地方。這真不幸啊,我也不會假裝我知道答案。Swing的應對方式是:搞出一拖拉庫的掛勾(hooks),使得它變成一套龐大無比的API而很難搞懂。


怪物問題

為了讓說明更加具體,讓我們回到線上遊戲的案例,假設,你已經極盡所能地把APIs與類別都弄好公開出去,可以用來創造與操縱法術、怪物、以及其他遊戲中的物件,假設你已經寫好許許多多的怪物類別了,我想你一定可以想出不少。

現在,假想有一個玩家,想要參與並寫一隻叫做OpinionatedElf小怪物。這是個故意設計出來的假設,就好像自動機停機問題(halting problem)證明自己的論點那樣不自然,不過,在實際上的確會發生類似的狀況。

假設,這隻OpinionatedElf其唯一的使命,就是大聲嚷嚷著他喜歡還是不喜歡其他種類的怪物,他會坐在你肩膀上,無論何時當你碰見一隻,譬如說獸人(orc),他就會歇斯底里抓狂叫喊著:"我恨獸人!!!啊啊啊啊啊!!!"(附帶一提,這句話就是我對C++的感覺。)

這個問題的多型解法相當簡單:找出你那150個怪物類別,每一個都加進doesMrOpinionatedElfHateYou()方法。

天啊,聽起來白痴極了,但是,這真的就是使用多型的解法,沒錯吧?如果你有一堆類似的物件(此例就是一堆怪物),這些物件都要根據某種狀況做出不同的回應,所以,你加進一個虛擬方法,然後替每個物件實作出不同的程式碼,沒錯吧?

顯而易見,這該死的解法行不通,即使你硬來(你沒辦法硬來,因為撰寫這隻小elf的玩家並不持有原始碼),也是一種差勁的設計法,沒道理把這麼特殊的方法(method)放進遊戲裡每個怪物物件裡,這點很清楚,假如一段時間後,我們發現OpinionatedElf有版權問題而必須移除掉,怎麼辦?到時你就必須回頭找出那150個怪物類別,一個一個移除掉。

就我所知(我並沒有聲稱自己是個程式設計高手,僅是個想知道正確答案的人罷了),正確解法會是使用執行期間型別檢查(runtime typing),程式碼大概會長的像下面這樣:

    public boolean doesElfLikeIt ( Monster mon )
    {
        if ( mon instanceof Orc ) { return false; }
        if ( mon instanceof Elf ) { return true; }
        ...
    }


我知道我知道,你這個OO狂,你可以寫出150個附加類別來幫助OpinionatedElf,每一種怪物由一個類別負責,可是,那樣並沒有真正解決根本的問題喔,問題核心所在是,這些眾多紛紜的行為全部都落在呼叫者(caller)身上,而不是被呼叫者(callee),那就是這些行為的歸屬之地,在呼叫者裡,就是那裡。

較高階的程式語言,對這個問題擁有稍微好一點的優雅解法,注意,我強調只是"稍微好一點",譬如說Ruby,你可以為其他類別加進新的方法(methods),即使是內建的類別也行,即使是你沒有原始碼也行,舉例而言,你可以把下面程式碼放進OpinionatedElf檔案裡:

    class Orc
      def doesElfLikeMe; return false; end
    end

    class Troll
      def doesElfLikeMe; return false; end
    end

    class ElfMaiden
      def doesElfLikeMe; return true; end
    end

    ...

如果還沒載入的話,Ruby實際上真的會把你指定的類別通通都載入,並且把你加入的方法放進每個類別裡,一般而言,這是個相當不錯的特色。

不過呢,在這裡讓我來說說這種作法的優缺。對Ruby(以及其他大部分高階語言)來說,方法(methods)就是放在雜湊表(hashtable)裡的項目罷了,每個類別分別有一張表,上面所述的特色,實際上發生的動作就是,跑進每個怪物類別裡,把你的東西塞進雜湊表裡去。優點有:

    * 所有關於OpinionatedElf的程式碼都被封裝在他的檔案裡面
    * 在elf檔案被載入前這些程式碼並不會被載入
    * 系統裡的任何其他人都可以向某物件詢問,問elf喜不喜歡他

缺點是當加入了新怪物,而elf無法辨別時,此時你需要有預設的行為。如果某人加入怪物類別小精靈(gremlin),你的elf就會卡住,亂吼亂叫地說"啊呀,那是什麼啊?",直到你更新加入處理小精靈的程式碼為止。

我猜想,如果你能以某種手法列舉出系統裡的所有類別,然後檢查是不是繼承自怪物類別,然後就應該能以數行程式碼達到上面所說的。若是Ruby,我打賭你做得到...不過僅限於已經被載入的類別,而對那些還躺在磁碟裡的類別可沒用啊!你或許還是可以想辦法解決,但可別忘了網路的存在啊...

話雖如此,需要有預設的行為這點,還不算太糟,還有更慘的缺點,緒程安全(thread-safety)是其中之一,這點深深地困擾著我──以這個案例來說,我不認為Ruby對於緒程安全所下的語意是定義清楚的,有把類別鎖住(class lock)嗎?載入elf類別前所執行的物件,其執行所在緒程,鎖定又會做些什麼呢?我日文不夠好,無法得知證明的方法存在於標準規格文件中還是在實作程式碼裡。

但是,真正的問題,真正困擾我的問題是,你的程式碼會跑進系統裡並且散佈到所有的類別中,這感覺起來,就像是違反了封裝(encapsulation)原則。

事實上,比那還要更深層一點,這感覺起來像是個差勁的設計,我們的情況是,有個觀察者,做出判斷的呼叫,而我們把判斷的程式碼塞進被觀察者裡,這不就好像是,我走到所有員工面前,交給他們一塊牌子,說:"請拿著這張牌子,上面寫著我喜歡或是不喜歡你"。這可不是真實世界的運作方式,而OOP不是應該要模擬這個世界嗎。


再次審視多型

嘿!至此,我已經說的相當明白了,多型不再能被當作銀色子彈了,即使是一個無擴充性的系統,如果你需要根據目標對象的型別來決定做什麼動作,那麼,把判斷的程式碼放進目標類別裡是不對不好的。

一個更實際更樸實的例子是,身分認證(authentication),讓我問你:如果你要設計一套權限管理系統,你的設計裡會有一個虛擬的doYouHaveAccess()方法,然後讓所有來人自行實作該方法?換句話說,你會請一個保全警衛,讓他去問每個人是否有權限進入建築物嗎?

絕對不會,你會在程式碼裡做執行期間型別檢查:

    public boolean denyEntryToBuilding ( Person p )
    {
    return ( p.hasNoBadge() ||
         p.isSuspiciousLooking() ||
         p.hasMachineGun() );
    }

但是,等一下,這些檢查並不是公開檢查類別啊,譬如,我並沒有說"p instance of MachineGunBearer",這是怎麼回事?

嗯,所謂物件的"型別(type)",實際而言,指的是它的類別(class)(幾乎是寫死的,就像是基因)以及屬性(properties)總合起來的合集,在執行期間可能會也可能不會改變。

那將是另一篇部落格了,但,我認為這代表了,型別最好由屬性而非類別來代表,因為類別有著與生俱來的固定性,但是在"傳統"語言裡,像是C++與Java,這會讓程式碼更難以共享,因為沒有支援語法委託(syntactic delegation)的特色,如果你覺得我說的沒道理,it's OK:我正在喝第三杯酒,快要不省人事了,讓我們把這個題目留到另一篇文章罷。

在此,我希望我把論點說的夠清楚了,也就是,當多重行為是目標對象的行為時,使用多型才有意義;當行為屬於觀察者一方的話,你需要執行期間型別檢查。


總結

嗯,我希望你在今天的醉後部落格有學到一些東西,我知道我有,其一,我學到Google的搜尋引擎的確有足夠的智能可以把"anikin skywalker"修正為"你是說anakin skywalker嗎?"哎呀,那群厲害的渾球,這不像是他們擁有著作權呀。

我也學到了,一篇部落格的長度應該剛好是兩杯葡萄酒,如果超過,你就會開始半昏迷語無倫次,打字也會打到地獄去了。

下週見,接下來的主題是...

Stevey's Drunken Blog Rants(tm)
(發表於2004年8月25日)

2011/03/28

兩個影片網站,InfoQ與Channel 9。

最近在網路上東點西連的時候,似乎常常會跑到這兩個影片網站,上面有不少好東西。

Channel 9 Videos about the people building Microsoft Products & Services
顧名思義,這網站以Microsoft的技術為主,不過也會有別的,例如Dr. Ralf Lämmel的functional programming教學五部曲,談論expression problem、type classes、language interpretation、monads、folds(aka bananas),哇,好多不懂的喔,什麼是banana(香蕉)啊?

InfoQ Tracking change and innovation in the enterprise software development  community
這網站很豐富,有人物訪談,例如請Rob Pike談談Go語言,也有技術展示,譬如Clojure的爸爸Rich Hickey介紹這個在JVM上的新functional語言,聽聽Douglas Crockford對JSON vs XML的看法也不錯。

世界真是大啊,網路真是浩瀚啊。

遞迴很重要啊

Recursion(遞迴、遞歸、迴歸),很重要啊。

最近,幫某人檢查他寫的程式,是用Matlab寫的,雖然我不太會,但他也沒用到什麼了不起的特色功能或是函式庫,所以我邊看邊學倒也OK。

他需要看一篇論文,理論證明的部份搞懂後,論文最後有跑程式模擬得出數據,但是論文作者似乎沒有公布原始碼,所以指導教授要他寫出程式出來,一來可以實際動手並且更了解論文內容,二來,有新的理論模型時,可以修改程式,跑出新的數據,測試看看新的模型可不可行,可行的話,我想那就是一篇論文囉。

細節部分就不多說,最難(對他來說)的一個地方是,給定n個東西,要用窮舉法排列出所有的排列組合(總共n!種),每種排列組合都要做某種運算,所有組合的運算值得知後,找出其中最大的值。

老實說,當我看到他用iteration(疊代)的方式來寫,也就是說用loop(迴圈)來寫,真的嚇了我一跳,因為,我看不懂啊!我雖然幫他用recursion的方式寫了那部分的程式碼,不過他執意要用迴圈寫,唉,搞不懂為什麼耶。經過一番努力後,我終於看懂網路上用iteration寫recursion的程式碼,不過我還是沒看懂他的程式碼,Orz。


遞迴很重要啊,很多演算法用遞迴寫是多麼自然、多麼簡單啊,會寫程式的人可別說你不會recursion。

翻譯:趕羚羊之程式設計宣言(The Motherfucking Manifesto For Programming, Motherfuckers)by Zed A. Shaw

文章:The Motherfucking Manifesto For Programming, Motherfuckers 趕羚羊之程式設計宣言
日期:2011.03
作者:Zed A. Shaw
作者的部落格:ZED SHAW


趕羚羊之程式設計宣言 (The Motherfucking Manifesto For Programming, Motherfuckers) 




草泥馬們看過來,
這是一份程式設計之
趕羚羊宣言。


我們是一群每天都在趕羚羊的程式設計獅,多少年來,我們被所謂的軟體開發方法論(software development methodologies)不斷地羞辱踐踏。

我們已經受夠了,不論是插屁(XP)、爭球(Scrum)、看版(Kanban)、瀑布(Waterfall)、軟體工匠技藝(software craftsmanship,也稱為戳屁屁"XP-Lite"),還是任何其他阻礙干擾程式設計的一切事物,夠了夠了,草泥馬的咧。

我們真的受夠了,我們被認定是孤僻且以自我為中心的蠢蛋白痴,說我們必須被加以操控,必須被束縛在強迫配對(Forced Pair Programming)的模式下工作,而沒有一滴滴的時間可以發揮創意創造力,因為,專案裡的那10位經理,沒有一個能夠做...程式設計賽羚羊咧。

我們必須摧毀這些妨礙程式設計工作的方法學,草枝擺啦。

我們的價值

他們宣稱會衡量的價值他們實際上衡量的價值 我們真正要幹的
個體能力以及與他人的交流分工許許多多可換算成薪資的工作時數程式設計,趕羚羊啦
能跑能用的軟體可用的單元測試(unit tests)程式設計,趕羚羊啦
與客戶間的協力合作把客戶榨到乾程式設計,趕羚羊啦
對需求變更的回應能力不穩定性與貌似老實卻有推諉不知情的能力程式設計,趕羚羊啦

我們認為,左邊那排米田共,其實就是把中間那排反過來看,而我們真正需要做的是在右邊那排...程式設計法克魷

簽名
Zed A. Shaw與會趕羚羊的程式赦祭屍。

變成一位程式色妓蝨獅然後趕羚羊吧

如果你不會但想學寫程式,那麼,我大力推薦我寫的書Learn Python The Hard Way,寫的真是太好了,不論你的程度高低,任何人都可以讀一讀,至少可以學會了解趕羚羊...ㄟ...程式設計的基本功夫,贛林老母啦。

寫程式取名稱令人抓狂啊

Reddit Programming上看到一個連結,OpenBSD shutdown.c, line 93,一看,笑死我了啦,哈哈哈。

1.34      cloder     93: void __dead die_you_gravy_sucking_pig_dog(void);

哇哩咧,這是什麼東東啊,左思右想就是不了解這個函式到底有啥用途?惡作劇?亂搞?開發人員發瘋了?精神異常?還是想不出好名稱了?

命名真的是一件很難的事情啊,取的不好的話心裡就會有個疙瘩在,取的好就神清氣爽,譬如有人把null terminated pascal strings以fucked strings稱呼之,真是妙啊,哈哈。有個叫做匈牙利命名法(Hungarian naming convention) 的規則,可以參考參考,不過根據Joel的說法,大家都誤解誤用這套規則了。

回到上面那個函式的命名,我想,應該跟命名學沒什麼關係,而是壓力太大的惡搞結果吧。