耀賢's profilePhotosBlogListsMore Tools Help

Blog


    June 30

    會寫程式的價值

    最近我閱讀一些 Erlang 源碼,從複雜的程式交錯結構中,體悟一些道理。首先是,這種程式語言特殊的地方是,幾乎所有的東西都視為函數,這也就是 Lambda Calculus 的精神。因為所有的東西幾乎視為函數,所以可以見到在一套源碼中,模組名稱、函數名稱、參數名稱等等,都融合在一起,一起為了達程目標而貢獻 ── 那是一組小宇宙,所有的物品都存在那裡,在需要的時候就可以取用。相較之下,普通的程式語言結構是,有一半以上的基礎概念在小宇宙之外,而在小宇宙之內的物品還得一件一件慢慢理清頭緒。

    另一則所見識到的事實,是在有一天照著 Introduction to Algorithms 書中提到 Dijkstra's Algorithm 的虛擬碼寫程式,我只照著書中的解釋寫了程式,一執行立刻就取得正確結果。我感覺到:「原來這就是所謂演算法。」好的演算法不但是清楚的描述過程,而且照著所描述的程式過程寫程式是立刻能跑。相較之下,差的演算法是,雖然照本宣科地做一些好像很有道理的描述,但是讀完了仍然不知道如何寫程式。最近就遇到自己的指導老師論文中的演算法,真是不容易寫程式啊!

    回頭想想以前擔任程式設計課程教學助理的經驗,所謂「會寫程式」這項技能可是被低估了。甚至,曾經聽過一些顢頇的說法:「程式只要寫久了就熟悉了。」雖然程式寫久了可以熟悉,不過,別人早以熟悉於寫程式的人,早就深植了另外更多遠超出熟悉之外的經驗了。寫程式這種事情,並不是熟悉了就停下來。

    所以,我覺得從今以後,我要認真看待「會寫程式」這事情的價值。具體來說,把人教會寫程式,不只是教學助理那一小時 150 元的行情,也不只是家教那一小時 300 以上的行情。但我不是說提高價碼,而是誰要我教會他寫程式,那代價不會太低。寫程式給你是一個低層次的價值,把我的「會寫程式」傳授給你是另一個高層次的價值。我認為自己值得這樣說,是因為,我學習程式的過程,在程式結構的推敲上付出的代價很高。但是,卻有些天真的人以為,程式只是寫了讓它能跑的算數。結果我的用心只能碰到一些人的盲目不理,對於這種情況,我只能說:「你真不知道事情全貌,看到一點點就以為看到了全部。」

    「會寫程式」的價值從哪裏來?我認為,是來自於在普通的程式練習中,逐漸累積對於程式結構的概念組成。程式的結構有些是很明瞭的,而另外有些是存在於一些「朦朧之處」 ── 也就是知識管理理論所指的半結構知識。對於程式結構的理解,應用數學系的人可算是取得了捷徑。

    「會寫程式」的價值如何評量?以家教比喻,不管我收你多少鐘點費用來教你,代價是由你所付出的心力決定。(當然,也由我所付出的用心決定。)假設教材沒問題、而溝通也沒問題,如果你只做到授課範圍所做的,你付的代價就非常高。因為分子是鐘點費,分母是你的收獲。如果分母接近零,那麼,我並不介意收到無限大的報酬。相反的,如果超越了制式的授課範圍、進入較高的概念層次,也就是討論到一些哲學式的議題,而你也能夠接受,你就會增加了分母,使代價變低;而我會希望因為加深了教學的層次,而增加鐘點費。

    過去的教學經驗中,我真的很受不了,面對許多人,一講到超越現實、現在層面的東西,談到一些較深化的主題,立刻就得不到好評。做人這麼現實、勢力,能有什麼好處。以前我會因為盲目的道義而自謙、自責,以為沒教好是有我一份責任;而現在,我個人覺得,對牛彈琴,牛不愛聽進那些音樂又不是我的錯。

    有人找我去教他寫程式,如果有誠意,如果講了願意聽,我很樂意教導許多東西,不收錢都沒關係;但是,如果找我去教他寫程式,卻感覺不到誠意,我懶得提供任何有用的資訊。因為,你找我去教你寫程式,但是我感覺不到你的熱忱、甚至感覺不到尊重,那麼,我會認為你應該停下來思考你自己的誠意在哪裏。不管我會的東西有多麼好,我沒有責任必須把任何難到極點的東西講到你隨便聽都會懂。但是有些學習者的態度很奇怪,明明是不容易的東西,你卻只想要你隨便聽一聽就懂。對於這種聽眾,我懶得好好面對你,因為,是你不想學習,而不是我不認真教導。(以上,是對於過去、和現在職場處境的怒吼。)

    現在的大一程式設計課程很可惜,學生是明明不認真學卻自以為想學,教學助理是想認真教卻教不了什麼東西。浪費很多時間,非常可惜!我認為大學教育應該思考如何深化教學層次,而不是安逸於持續簡化教學過程。

    June 21

    言不由衷

    語言是很多樣的東西。一句話可以講的明白簡單,或者也可以包含深遠含義。

    很久很久以前,我是講話、聽話直接的人。我沒有思考過講什麼話,事實上,幾乎不講話,所以不需要思考。 (可說是所有的話都只在思想中繞著,幾乎不講。) 一講出來就是很直接的意思。後來,在大學中遇到 W.Y. Chen 老師,見識到話中隱藏它種意思的話語模式。漸漸也感染到這種表達方式。

    許多時候,講話就不再是話直接講的意思了。就好比《暗戀‧桃花源》舞台劇中的一段對話,劇團老闆與幫手的一段爭執:

    老闆:「這是什麼東西?」
    順子:「這是一盞街燈啊!」
    老闆:「我不是在問你它是個什麼東西!」
    順子:「可是老闆剛剛你明明問我什麼東西…」
    老闆:「我是說為什麼它現在還在這裏?」
    順子:「為什麼它在這裏? 大概是因為它…」
    老闆:「我不是說為什麼它現在還在這裏!」
    順子:「可是老闆如果我剛剛沒聽錯, 你剛剛是說為什麼它現在還在這…」
    老闆:「請!你!把!它!搬!走!這樣明白了沒有?」
    順子:「早說嘛!」

    在挑選簡單或繁複的詞語時,我漸漸學會了擴充我的語彙。大約二十年沒好好學過講一段話。但是,接下來常常遇到一些問題,有時候講得深了且含義多了,雖然自己腦袋模模糊糊之間仍能掌握住各種層次的意義,但是聽者不懂。又或者,有時候講直接、簡單的話,意思就是話字面的意思,聽者反而想要猜測其中有什麼含義。

    基本上,我是個複雜的人,講話包含了多層次的意思,有些部份自己的腦袋只能朦朦朧朧地抓住形貌。而且,我還是個心意與口語意思違背的人。就像前面所提到,劇團的老闆說了:「這是什麼東西?」真正的意思是「這東西為什麼在這裏?請把它搬走。」我講話可能像這樣,有時候只提出前提,有時候話中隱含著一些提示訊息。我認為這樣話與意義的隱含關係是身為人能斷定的自然推理順序;並且非常不能瞭解,曾經遇過好些聽者、對象,就像這例子中的員工順子一樣,思路是片斷的、零碎的,無法收到老闆希望傳達的意思。也或許,老闆講了明白的「早說嘛」的句子,順子反而會有另一層的解讀。

    我覺得,解讀與欲求相符──或者,與不欲求相符。不想要接受一種意義,於是,即使傳達那種意義的是簡單語句,人也會避免理解它。我遇過好多無法溝通的情況,我講了簡單的句子,卻被認為「聽不懂」。是真的聽不懂嗎?或者是,對方自己心裏的貪念、或偏見在作祟?

    在我唸書期間,有位老師老是愛打擾我,使我無法順心完成課業。我寫過長篇的信給他,告知各面細節,換得他說句:「不曉得學生在想什麼。」我覺得,寫了很多,他卻似乎一句文字也沒看進眼底;於是,我就寫直截了當的句子給他:「我不喜歡你打擾我唸書。」結果,換來他更多的緊盯。快要急死我、氣死我,因為我根本不是他的學生,憑什麼讓他這樣打擾我呢?而且,不管我的信件寫得繁雜或寫得簡單,總是被當做「無稽之談」,那麼我的時間都白費了嗎?

    這件事情,後來我想了想,覺得理由是,他自己認為我不是容許忤逆他的人。不過,很抱歉啊,我就是被打擾而不能唸書,很急、很氣了;我認為他侵犯我的人權,所以就偏偏要向他抗議,即使惡言相向也沒關係。

    到現在,我還是不會講話。這或許很糟糕;不過,我認為聽人講話卻聽不懂的其他人,比較糟糕。先把你自己心裏的石頭移開吧!

    June 14

    線上辦事情

    辦什麼事情都要線上化,是很可怕的趨勢。我想說的是有關線上更新軟體。

    有許多軟體內建、並且預定軟體自動做線上檢查及更新。事實上,我們常常不需要這種自動功能。正確地說,我們一點都不需要無謂的、煩人的自動處理。有新版本,謝謝你通知我;但是,假如你要自己突然跳出去下載新軟體,我說:不必了!

    這是多到有一台電腦會放久一點不使用,而有的感想和牢騷。很久不用的電腦,後來開了、用了,就是因為需要使用。然而,因為放置得久,距離上次更新時間也比較久。這時候,許多軟體就仿照病毒碼更新模式,每一樣軟體全都冒出訊息說:很久沒更新囉,很急喔,很迫切喔!搞得我突然覺得壓力很大,好像我手邊的每一台電腦都不能放很久不使用。

    其實,說「久不更新比較有危險」這種話,是認定自家廠商的舊軟體是有毛病的,不是嗎?如果你那廠商對自己開發的軟體品質有信心,不需要安排自動更新,不需要發出急需更新的請求。

    對使用者來說,軟體舊沒關係,穩定比較重要。

    而對開發商來說,如果你帶種,就不要用自動線上更新來煩死使用者。即使有自動更新,起碼要提供關閉自動更新的功能。

    我不是活在網路上的人。我不希望來自網路上的一些訊息特地逼我去更改我的軟體和系統。

    June 13

    函數語言的實用

    最近很認真在複習函數語言,而且要將語言轉往實用的用途:例如,用 Lisp 寫個 telnet BBS 的客戶端程式。

    在寫程式者的立場來看,用函數語言寫程式比較快;不過,前提是要對函數語言中的許多特性很熟狠熟──函數語言的學習曲線是蠻高的。快的程度,我覺得普遍的 ACM 程式設計比賽的題目,用函數語言一下子就寫好了,但同樣的時間,用普通語言可能還在刻劃資料結構吧!

    回頭想一想,大學期間聽過老師說,學 C 語言較好, C 程式一會就全會。但現在我覺得,可以讓我選擇當初基礎程式課程是學 Haskell 或是學 C 嗎?其實懂或不懂電腦機器處理 C 語言的方式,真是小事一樁。

    而目前試作函數語言的實用程式,比較不清楚的概念是:該怎麼讓函數語言寫的程式,與眾多的普通語言寫的程式通訊。

    June 10

    小說《道士下山》

    這是一本近現代武俠小說, 筆法充滿的連貫的故事性、並且蘊含許多許多武俠的韻味。這不是一本非常重要的書,卻是一本很迷人的小說。

    聽聞到這本書,以為是出版很久的書了;去書店找不到而問服務人,才從新書專櫃拿到這本書。這是一本最近出版的書啊!作者是大陸人;看看出版頁,覺得大概是將他的好些日子之前的作品翻印成繁體中文書本吧。

    June 08

    美妙的語言們

    最近都在重新練起過去學過的一些異質程式語言,像 Prolog 、 Lisp 、 Haskell 、 Erlang 等。所謂異質是指,有別於普通程式語言,它們是比較奇怪的。

    普通程式語言,像 C 、 Java 等等,都是指令式的。每一行程式碼是叫程式做一小步動作,而且差不多都是很小一步;而假如那一行程式是呼叫某一函數,就只不過是變成做另一個比較大一步的動作。這種程式語言寫起來的問題是,面對的寫程式需求及題目有多少,就要寫多少程式。

    而異質程式語言們, Prolog 是邏輯式語言, Lisp 、 Haskell 、 Erlang 都是函數式語言。 Erlang 是一開始用 Prolog 開發,後來持續改寫的語言,本來是易利信公司的當家產品,後來釋出為開源軟體; Erlang 來自 Prolog ,所以乍看很像,但是 Prolog 是邏輯式語言,而 Erlang 竟然長得比較像 Haskell 、函數式語言。也許是程式語言發展的概念有志一同,或者是 Erlang 開發過程中參考過 Haskell 吧。

    最近一直練這些風格迥異的語言,而且變得更習慣了。習慣了之後,發現以前用普通程式語言難解的問題,在這些異質語言手中是小問題,寫少少的程式碼就可以解答,而且可接受解答的問題範圍還比較大。後來再回到普通程式語言上,就不知不覺地會運用函數語言的解題想法處理,思考變得非常輕鬆。果然,人說「程式邏輯概念非常好」這句話,並不是指誰天生恰好會寫程式,而是真正上過邏輯課程。

    以前,只會普通程式語言,都以為寫程式只要多練多記就熟了。另一方面,普通程式語言的愛好者還有一項見解,以為所謂的「程式很強」是懂得極度壓縮程式碼,或者是巧妙地使用程式內部運作機制。現在就知道,以上二大項不盡然如此。將普通程式語言練到會的舉動,可以比擬為一直背誦課本;背久了不求思考突破是不行的,普通程式語言的精通之路也是如此。但是,很矛盾的是,普通程式語言練多了就是陷入無聊困境,因為缺少一些讓你變聰明的額外因素。

    函數式語言的寫作風格,大約有二種走向。第一種走向,是用簡單的方法寫函數:要解決的難題拆解成許多簡單的小函數,隨著函數組合的威力而取得問題的解答。函數簡單,就容易寫,也只要花相當少的時間,就寫出可執行量相當大的程式份量。另一種走向,是善用函數組合:函數式語言的數學性質很強健,於是,數學中的許多律,像是分配律、結合律、交換律等等,在函數式程式中也成立;意思就是,某一組函數組合等價於另一組函數組合,因此一組函數組合可以推導為另一組函數組合。我可以用不預期、但符合數學原理的方式,幫一個用直覺方式寫好的程式推算出另一個功能表現完全相同、而計算效率更好的程式。以上二種風格,目前我非常熟悉第一種,但第二種仍要再磨練一陣子。

    ---

    最近練 Prolog 時,回想到我從來沒閱讀過一本 Prolog 教學手冊。我仍不知道如何用 Prolog 做個基本的標準輸入與輸出。於是去找圖書館藏,母校的圖書館竟然將所有的 Prolog 書籍都收入密集書庫。不過,我調出一本叫 Programming in Prolog , 1980 年代的著作,真希奇。