也談編程工具
我總是避免在博客裏談工具,因爲怕被扣上「工具黨」的帽子。今天看到王垠聊到編輯器與IDE,才想起來我似乎沒有在博客中寫過相關的話題。接觸代碼世界也已經十餘年了,這一拍腦袋,覺得好多話想說。
首先表個態,爭論工具孰好孰壞意義不大,就跟編程語言的爭論一樣無意義,因爲這些東西都不存在絕對的「好壞」,而只存在「適合不適合」,脫離前提的討論是空泛而不切實際的。既然這樣還寫這篇博客幹嘛?只是隨想,算是滿足一下我的傾訴慾望。
IDE
IDE是個很贊的「再發明」,之所以說它是「再發明」因爲我認爲它已經被發明過,只是當時人們沒有認出它。這個我會在下一節聊。喜歡IDE的理由很簡單,因爲它特別省事,尤其是在應付編程語言的知識集遠遠大於人腦對相關知識的記憶集的時候。Java就是個再好不過的例子,它的知識集不僅龐大,而且還時常令人困惑。就其龐大而言,看看它的文檔和相關的書籍就知道,其厚度是可以考慮作爲防身道具的。而對於「令人困惑」我得稍微解釋一下。困惑來自語言中一些對類似概念的
inconsistency。比如 Java 中的 Array、ArrayList、String,我們時常要獲得它們的長度。對於Array,我們得用array.length
,是Array的一個屬性;對於ArrayList,我們得用arrayList.size()
,是ArrayList的一個方法;對於String,我們得用string.length()
,是String的一個方法。
如果沒有IDE,那解決以上的兩大問題就必須藉助於查詢文檔,這樣一來,效率就下降了。有人說可以熟能生巧,那也只是熟手被迫擴大了自己的記憶集而已。這時候IDE的好處就顯現出來了,自動補完和語法提示拯救了大多數 Java 程序員。而且IDE與身居來就「傻瓜模式」,通常從安裝到使用都不會超過30分鐘。
另一個優點是伴隨它的自動化來的,我們知道IDE裏都有很多工程模板和代碼自動化工具。這些東西對於剛入門的程序員特別有用,那些文件結構和代碼結構就是一種行業標準,學習這些標準有助於使自己的成長。
而其缺點也是從「傻瓜模式」引入的。我有多次爲了配置IDE環境而浪費了四五個小時的經歷。簡單的加一些包、修改編譯器版本什麼的倒是容易。但是如果項目比較複雜,牽連到一些其它技術和語言,那可能會要費點心。如果你所使用的技術的社區步伐比較快,那恐怕IDE還不是很支持,或者只支持較舊版本。沒錯,IDE是爲「大多數情況」設計的,你很難保證自己正在開發的項目是不是「大多數情況」。
另外,IDE對用戶而言,是個黑箱,其內部運行機制我們只能靠想當然或查文檔。這也給定製化IDE造成了一定的難度。不知你有沒有遇到過,反正我是遇到過一些小問題怎麼調都有問題,之後重啓IDE或重裝才好。不管問題到後來有沒有解決,都讓你感到莫名其妙。所以現在市場上比較好用的IDE都是非常有針對性的,很少能做到一個IDE就滿足大部分開發需求的,即使有,其體驗也令人着急。
最後是有關權限的問題。用 Windows 的用戶可能不太會遇到我所描述的情況,但是相信用 Linux/Unix 的朋友應該是遇到過類似的。就是項目放在一個不屬於用戶權限的目錄下,要編輯的時候就必須給IDE super user的權限,而IDE的行爲很多時候都是黑箱,且可能涉及到除要修改的文件以外的其它項目文件,我要非常小心地操作,因爲「權利越大,責任越大」。
編輯器
在這個討論中,與IDE相對的就是文本編輯器了。文本編輯器的種類可就多了,有經典的 Vi 和 Emacs,還有較爲現代的TextMate, Sublime。這個小節裏我將特指文本編輯器爲那些有較好CLI支持的編輯器。爲什麼?你應該還記得我在前一節說到IDE是被重新發明的吧,其實我想說,IDE初見端倪還是在Unix環境下。我並不是第一個這麼說的人,如果你看過我們翻譯的「Unix as IDE」,你就應該明白爲什麼我這麼說了。這裏我簡單闡述下:首先是Unix/Linux shell下能實現幾乎所有現代IDE的功能,它甚至能更好地實現。而shell下的可編程性又使得個性化配置變得簡單可控。所以上面提到的IDE的缺點被全部修正。當然隨之而來的是易用性問題。如果僅僅是用好shell下的編輯器,其學習曲線倒也還可以接受;但是要把Unix/Linux當作IDE一樣用好,可能不花上個一兩年是不行的。不過這中時間投資是值得的。
這種靈活性和可編程性很大程序上得益於之前被王垠噴的Unix/Linux的以字符爲通信媒介的設計思路。Unix/Linux的設計中,有很多「只做一件事並把事情做到最好」的小程序,這些小程序接受字符串命令並執行。這樣一來,它們即可以單獨運行,也可以作爲一個更大作業的一部分來運行。正是因爲字符串式的控制方式,我們才能如此靈巧地使用這些小程序。想想看,如果這些小程序都是通過對用戶不友好的API來呼叫,系統會怎麼樣?變快了,可是丟失了一些靈活性。這種靈活性,我常常用一個比方來說明它,試想待解決的各種問題就像用石塊鋪的地面,要想弄平整這塊地面,就必須拿那些顆粒更小的黃沙來填充溝壑。而Unix/Linux的這種設計思路正是這種黃沙,這才使得Unix/Linux可以勝任幾乎任何工作。
上面扯的這些可能在沒有相關經驗的人看來有點空,下面我們來點接地氣的,說說我是怎麼用 Vim 以及相關集成環境的吧。由於工作需要,我得寫 Python、Ruby、PHP、Java、Go、JS等相關的程序(其實還包括我現在寫博客的markdown在內的很多文件支持,這裏就不一一列舉了),項目中出現多語言的情況也很多。爲了適應這種詭異的需求,我寫了一套自己的Vim配置。不同編程語言的支持,對我來說只要有語法高亮和正確的縮進以及不用太智能的自動補全就差不多了。除此之外,剛剛我說了很多它的靈活性,例子之一就是我在做RoR開發的時候,TDD就是用 Vim + tmux 的快速反饋的方式來做的。那這麼做到底有多爽呢?感覺很像是Emacs下用slime做clisp的開發,隨寫隨eval。這些功能性都是較現代IDE有過之而無不及的。
說完功能性,我還覺得使用文本編輯器寫程序能使你更快地變成更好的程序員,至少對我來說是這樣。爲什麼這麼說,首先是「去自動化」,這些經典文本編輯器都是有非常完備的自動化功能的,但是並不會像現代IDE那麼簡單獲得。於是在順利使用各種自動化提高效率之前,你可能得手動做好多從零開始的事情。在此過程中你可以學習到很多技術細節。比如說用某某框架,一些現代IDE可以自動生成好多東西,包括一些配置文件也都是點點按鈕。其實這些技術細節都在那一堆項目文件裏,如果能經自己手,並在特殊情況下按照自己的需要修改這些文件的話,你學到的要比用IDE生成來的多而且快。有些東西,是欲速則不達的。
再來便是思維訓練。記得剛剛學習變成那會兒還只是簡單的藍色窗口下的BASIC,出了問題了只能靠print
和想,沒有先進的debugger。後來用上了IDE之後一度迷戀上使用圖形界面debugger這種便利的工具。後來發現,其實往往通過推理的方式來debug更加有效,甚至能預見到還未出現的bug。文本編輯器裏沒有什麼便利的debugger,要用也只能用命令行下的debug工具。這時候你只要還有點惰性,就不太希望輕易使用debug工具。這種思維訓練提供了我全局思考和程序化思維的能力,變成一個活解釋器也不是壞事不是嗎?
根源?
我曾看到這樣一種說法,說如果一門語言設計得足夠好的話,IDE是一種多餘的存在。因爲IDE本身就是爲了很大程度上彌補語言設計的不足。聽起來有點偏激?我暫不置評吧,畢竟這篇日誌是談工具,而語言,作爲生產材料,或許可以作爲以後某篇日誌的主題。引入這個評論,其實我是想說分析生產工具無法徹底將其與生產材料分開討論。而確實,不同的編程語言其需要的自動化類型也是不同的。對於設計較差的編程語言,自動化可能更多的是在生成代碼上。而對設計較好的編程語言,自動化可能更多的是放在生產環節上,比如自動測試、編譯、部署等。生產環節的自動化往往是需要很強靈活性的,而前面我也已經說了,這種靈活性恐怕是大多數IDE不具備的,除非有像google內部專門的team做相關的IDE定製化開發的支持。
先拋開語言的優劣,我覺得目前我看到的最想用的IDE就是LightTable。當然,如果它能兼備靈活性,我會果斷拋棄現在我在使用的開發環境方案。