The Old Blog Archive (Traditional Chinese), 2004-2009

Archive for February, 2009

學 Python: 兼談成人的語言習得

代替一篇欠一位朋友很久的文章。

曾經有位朋友問我當初是怎麼把 [C, C++, Ruby] 等語言學起來的,但是這種事就跟問我當初是怎麼回會腳踏車或是學會騎機車一樣,為已經模糊的記憶加油添醋的成份太多了。

最近倒是因為有個新的工作項目,雖然屬於熟悉的領域,但是很多相關的工具都還沒準備好。這似乎是個學新語言的好機會。於是想說來學 Python。

幾年前,我快退伍的時候,當時跟一位 PHP 屬於神的等級的學弟請教,如果這時代要寫程式,應該學哪些東西。在許多當時聽來相當陌生的名詞當中,Python 是其中一項。但我後來卻去學了 Ruby ,而且一直沒有動機學 Python ,因為:

  1. Python 跟 Ruby 同質性太高。至少對我來說他們都想解決同樣的問題
  2. Ruby 的 OO 比較對我的胃口(Smalltalk 系、與 ObjC 有表親關係)
  3. Ruby on Rails

不過因為新的工作內容,需要找一個參與各方都會的語言來做為工具開發用,突然讓 Python 變成了一種必要(我是唯一在工作開始前還沒有真正接觸過 Python 的人)。

目前採用的方法、進度跟心得是這樣的。

我沒有找書來看。唯一憑藉的是 Python 官方網站上的文件。這其實還蠻危險的,因為官方網站的文件範例有點稀少(好比說在講解基本型別時,很多細微之處沒有舉很多例子)。與此相關的是 Python 3 與 Python 2 有很大的差別,問題是 Python 3 網站上的文件沒有適時標出問題所在。好比說,所有 Python 2 教材裡關於 map(lambda x : x * 2, (1, 2, 3)) 的例子到 Python 3 上面執行結果絕對不是教材說的那樣。

過去學其他程式語言,大體上最重要的幾個一定要知道的東西,目前也都過了一遍。一般說來一個程式語言最重要的資料型別是字串(這個真的在語言教學中被大大低估),尤其是 Unicode 的問題,任何在這個年代撰寫程式的人都有機會碰到。然後就是控制結構,知道迴圈跟條件分支怎麼寫。再來就是語言特性了,好比說 Python 就是 tuple/list 的特性、怎麼樣使用 map-reduce 等操作(後者在 Ruby 有個非常不像話的名字叫做 inject …)。不過我還沒碰觸到 Python 的 OO。

知道了控制結構跟基本型別的操作,接下來就是 stdio、檔案開啟、取得系統物件(例如像 sys.stderr, sys.argv 這類每種語言教法跟意義稍稍有點不一樣的東西),然後就是看 library reference 找自己需要的程式庫來完成手上的工作。粗淺的心得:SQLite 內建支援真不錯。Regex 似乎沒有 Ruby 方便(但是看來沒有什麼語言 regex 能比 Perl 方便……)

我跟朋友們說,其實成人學語言是相當尷尬的。一方面,你不太需要其他形式上的語言知識(你不再需要知道什麼是名詞、動詞;你不再需要知道什麼是浮點數、Unicode字串);另一方面,你卻也失去了從頭學語言的緩慢樂趣。尤其如果是為了完成工作的需要而學語言,慢慢嘗試探索、從笨拙的風格慢慢學習精簡、符合「成語」(idiom)的用法,這些都變成了一種時間的奢侈。

然後可以想見的是,這樣學語言,一定就會在某些幽微之處撞牆,而且死得很難看。君不見大家都說直接用 printf 寫 SQL statement 有多危險,但是你需要某種緩慢的閱讀速度,才會了解問題的根源跟解法。泰西諺語所謂:A little knowledge is a dangerous thing.

也就是說呢,我以前一直在尋找好比說「給 C++ 程式設計者的 ObjC 快速轉換入門」或是「給 C 語言程式設計者的 PHP 快速入門」這種可以只要拿著小抄一一對映過去就的指南,其實是不存在的。或者說,天底下沒有這麼便宜的事情。所有語言的背後或許全部都是共通的(這是很重要的假說),但是至少人間世的語言間(包括了程式語言)沒有存在完美的、唯一的一對一映射。

另一個困難在於,即使很快地克服了語言外貌所造成的障礙(熟悉了語言的文法),但是「習慣用法」(convention)才是最困難的,而那完完全全是時間的產物。Convention 除了包含「大家都習慣怎麼說/解決這個問題」外,還包括了「有那些不具文的、遇到了就要閃躲的坑洞」,更上一層甚至還包括了「直覺上就應該採取的路徑」或「直覺上就知道這是不可行的路徑」這種東西。

當然,最終來說,成人語言學習還是要回到任何語言學教科書開頭就會教你(而很多論辯語言的人都從沒搞懂)的兩大基本不同概念:能力(competence)與表現(performance)。你只要能用一種語言來從事活動(例如:閱讀別人的 code、靠著 copy-and-paste 解決問題),都可以說是具有一種語言的能力。但是你說得怎麼樣、寫得怎麼樣,上不上得了檯面,則是有可以評量的標準。其實,自知之明(know thyself!)講的也就是這麼回事:知道自己有能力並不代表能夠有好表現,你得惦惦自己有多少斤兩,有多少「才調」(tsâi-tiāu)。具體來說,會了英文不代表寫出來的東西不會被 native speaker 拿去投稿 engrish.com,「知道」什麼是 SQL 跟怎麼樣寫出不會被人 inject (此處 inject 不是 Ruby 那個 inject)的 SQL 操作也是天差地遠兩回事。

這當然跟自己的目標很有關係。如果你的目標不是「我要精通 x 語言」且沒有付出相對應代價、通過相對應考驗(這也仍然是兩回事,付出過苦工,跟上不上得了檯面沒有必然關係),但是卻又有著工作上的責任背負在身,此時最好還是遵循這個簡單的指導原則。這是一句鄉民用語,謂:「閃開,讓專業的來」。

至於我呢,在達成了內部工作需要的目標後,或許還是應該真的找一本好的書來讀,然後尋找其他用得上新學語言的場合來精進。如果有時間的話──因為忙碌而造成沒有辦法緩慢下來,以及因為有了既成的知識而再也無法像初心者一樣純真地看待任何幽微的細節,這兩者或許是成人語言習得 (language acquisition) 的萬惡之源。

寫程式真難

正所謂「啊嘶漫長,生命苦短」(ars longa, vita brevis)。

有一天我同事在 review 我多年前寫的 code ,他問我:為什麼明明可以用 Objective-C 做的事情,你卻偏偏要用 C++ 來做?

(明明 Cocoa 就有字串相關的操作,為什麼要把字串轉成 C++ 字串,操作完再轉回去 Objective-C 呢?因為那時我不知道嘛……)

後來我們又在另一個場合聊到這個問題。我說:熟悉一個 framework 比熟悉語言還難啊…

同事說,也是啦,熟悉 framework 之後還要熟悉 convention…

我說,熟悉 convention 還不夠,你還得熟悉原廠有哪些 bug …

TapExpense 2.0.1 発表

上週六凌晨 TapExpense 2.0.1 正式上架。這一版修正了「在分類/貨幣/群組等清單調整過順序後,新增項目無法正確被選取使用的問題」,同時也修正了繁體中文介面的錯字及用語。

2.0.1 Lite 版本還在 Apple 審核中,應該很快也會上架。

另外,TapExpense 再度登上台灣 App Store 財經類軟體排行榜。以後也要請大家繼續指教,再次感謝每一位使用者!

新発売:TapExpense 2.0

經過幾個月的努力,TapExpense 2.0 於星期天 (2月8日) 上市

這是一次大改版。TapExpense 1 的設計目標是提供簡單的記帳功能及報表。自從 2008 年 7 月開賣以來,我們從使用者回覆中學到很多。想要加入更多新功能,又想維持原有的簡單操作和設計,於是我們決定從頭重寫每一行程式,並且反覆調整,有了現在的 2.0。

2.0 最重要的變化有三項:支援收入項目、密碼鎖,以及匯出 Excel 試算表 (XLS) 檔案的功能。

當然,不能少的還有意門設計操刀的新 icon :

除了剛剛提的三大新功能外,TapExpense 2.0 也有許多細部的調整與改進。例如可以加快輸入速度的數字鍵盤、自定日期範圍的報表、可以調整順序的分類/匯率/群組列表、增加了公務報帳(特別是美國公司)需要的群組(或者旅次)及廠商(或店家)欄位,也完整處理了不同地區的日期和小數點格式等等細節。這個版本的操作、動線和 UI 反應比第一版來得更加簡潔流暢。我相信喜歡第一版的使用者一定會更欣賞第二版的種種提昇。

我自己也是 TapExpense 2.0 的新版受益者。2.0 針對國際旅行的需要做了很多細微的調整。同時,因為有了群組功能,我可以開始在 2.0 上面同時記錄自己的帳和公司的帳。

更重要的是──我們從顧客身上學到了很多很多。我們期許能用 2.0 回饋給我們的顧客,期許 TapExpense 能成為 iPhone 及 iPod Touch 最簡潔好用的帳務軟體。

我會在接下來幾週內陸陸續續分享 TapExpense 2.0 的製作過程,以及一些細部的功能設計。

TapExpense 的售價為美金 4.99 元,在全世界各國的 iTunes App Store 上販售。2.0 同時也推出免費試用版本 (lite version)。試用版本功能跟付費版本一模一樣,唯一的差別在於試用版僅僅顯示及匯出最近七筆資料。您可以持續使用試用版記錄收支,購買了付費版後,可以點選資料轉出功能,將所有帳目匯入付費版本的資料庫。

詳細的說明,可參考我們公司網站,或是直接進入 App Store 的產品頁(付費版試用版)參觀選購。

謝謝大家!

丟書與電子書

看了這一篇文章:John Siracusa 談論電子書。文章很長,如果你還沒有分心過去看,以下是我的一些感想。

過去 15 年間因為不同的理由丟過兩次書籍雜誌,今年排定有新的一輪。我還沒想到明確的方法,請二手書店的人來收可能是其中之一。

有些書以為會收藏很久,或是用很久的。這一輪棄書準備丟掉很多字典。大學時代以前的英漢字典已經幾乎沒有參考價值。後來買的各種字典,不少也難逃過時的命運(例如:1990 年代中葉德語拼寫改革之前的學習用字典)。隨著字典編輯方法的升級(例如以語料為基礎的編纂方法,替代以有限數量菁英學者的產出),可以料見的是字典過時的速度也會變快。

電腦類型的書就不用說了。2004 年退伍的時候,去買了當時覺得很重要的書:Linux 入門指南(兩本)、FreeBSD 上手指引(一本)、PHP 與 MySQL 程式設計等等,甚至還買了當時流行的軟體重灌跟系統效能調教雜誌等等。這些書事實上連二手販賣的價值都沒有,擺在書架上非常礙眼(中文電腦書是所有中文書籍類型中最醜、最沒收藏價值的一類)只能打成紙漿。

後來技術書籍的解法之一是 Safari Bookshelf。嚴格說來 O’Reilly 的這個解決方案已經不能算是「書」了,但是所有裡面所用的詞彙和想像都圍繞在書的周邊。

然後最近也在認真考慮 Kindle。Kindle 對我來說的真正價值在於節省購買 hard cover 英文書籍的費用。買 hard cover 的誘因在於書本內容時新,而且比 paperback 早出。但是 hard cover 集所有書本的缺點於一身:昂貴、笨重、造成日後收藏與搬家的負擔(我很早就放棄了要當書本收藏者的人生目標)。而且不方便的事實是:雋永的書比例並不如想像的高。

(為了做研究的需要,或是因為對於知識領域的深度追求,那是另一回事。至於純粹的閱讀樂趣,我目前的感覺是:花幾百塊錢台幣去購買一次閱讀的體驗是值得的,但是並不代表那個體驗需要被再次經歷;另一方面,曾經有一次突然驚覺,有位小說家透過他筆下角色宣稱「我只讀已經死掉的人寫的東西」或許是有道理的)。

Siracusa的文章有一大部分(前 1/3)其實更像是在為「書」尋找一個更好的定義。音樂沒有這個問題:內容跟載體很早就是被區分開的。但是「書(寫?)」還擺脫不掉紙張的軀殼,連帶限制了(這是我的延伸解讀)我們對閱讀的想像。然而事實如同 Siracusa 說的,我們早已經在非紙張的閱讀媒介上花了無數時間。因此技術本身不是問題所在,圍繞在這一個行業/產業的本質性問題才是關鍵。

Siracusa 的文章到後來變成了在敲邊鼓,認為 Apple 大有機會吃下這一個新興領域。他同時並不完全看好 Amazon。我自己的想法是:書本(或者是那個還沒找到更好名字的「那個東西」)的 “iPod Moment” 還沒來到。

但我其實是衷心希望這個 iPod Momenet 早一點降臨的。到那個時候,我就可以大聲說「我不讀書」,而意義就跟「我不再聽錄音帶上的音樂」是一樣的。