Lisp, I'm back.
沉寂了很久, 打算重新開始Common Lisp的學習和研究工作。
離開的兩三年裏, 身邊發生了很多變化, 在技術領域裏把大部分時間投入到了學習其他語言(Haskell,日語!!!...)和概念(函數式, 類型系統...)裏去,
每天周遊在家庭生活, 公司工作和語言學習中,疲於奔命的結果是蒐集了大量的Lisp論文和書,卻沒什麼時間去看看幾眼,
今年開始又有相當的時間可以自由支配, 於是最近有一種衝動想回到闊別兩年的"事業"中去,
而就在上週的某個晚上我給自己進行了Project Kickoff(一大包Potato chips和Choco, Cheers!)
Lisp學習的新方法
這次不僅僅想按照過去的方法從學習語言特性,實現以及開發應用的角度去理解Common Lisp。 它的體量龐大,歷史背景的厚重是讓學習曲線看起來陡峭的原因。 SBCL的一位資深開發者也曾建議想要參與SBCL開發的入門者不要試圖像閱讀書籍一樣系統性的學習它, 這樣會立刻遭到挫敗。
最近我領悟到了如何去突破這個陡峭的學習曲線, 我們應該像學習OS一樣學習它。 Common Lisp那奇於他人的REPL, 解釋環境中的宏展開,運行時的增量編譯/加載, 龐大的標準函數和對象庫,以及代碼和數據的模糊界線等等,這個讓人感覺如此動態多變的巨型怪獸與一般的編譯型語言是如此不同,以至於讓很多人或沉迷於此或望而生畏。我發現在這些特性中有很多是與現代OS的行爲如此吻合, 確切的說它們更像現代OS行爲的原始雛形(如果去看看語言發展史,你會發現早期的語言和OS並不像現在的分工這麼明確)。 拿Linux系統作類比的話, REPL就像Shell, symbol對象就像文件名(inode), package就像單層目錄(而且還支持創建符號連接), 函數和對象就像可執行或數據文件(在runtime裏的底層編碼甚至就像FS對文件的編碼), 標準庫裏的包和對象就像系統目錄和文件, intern一個symbol就像touch一個文件, compile/compile-file以及implicit compilation就像gcc, 定義(編譯)一個函數就像用gcc產生一個可執行文件, 調用它無非就是輸入參數執行該文件。。。
如果你擁有一個這樣的語言(OS), 你確實可以在運行語言(OS)的同時,去幹預(操作)它,去重新編譯它的一部分(覆蓋文件)等等, 去做些其他語言所不具備的行爲。當然, 說這些是OS行爲的雛形是有原因的, 畢竟它缺少對安全(權限(用戶), 沙箱(進程)), 穩定(用戶層與系統層), 操作性(GUI) 等保證系統運行和可用的管理機制。
因此,我們也許可以像學習和研究OS一樣去了解Common Lisp,而不是一般的語言學習方法。 在學習OS時,我一般用以下的方法,
- 瞭解用戶界面: 學會怎麼操作用戶界面, 會從錯誤中恢復, 執行簡單的操作。
- REPL的操作方法, REPL在何時解釋腳本(就像執行shell script)何時運行二進制(就像執行c程序), 何種操作是安全的何種是危險的(比如rm -rf /)
- REPL的操作方法, REPL在何時解釋腳本(就像執行shell script)何時運行二進制(就像執行c程序), 何種操作是安全的何種是危險的(比如rm -rf /)
- 瞭解文件系統: 文件是如何存儲, 分佈, 底層表示是什麼; 一般的操作(CRUD, 查找...); 主要系統文件的作用。。。(從宏觀角度去了解文件系統,而不是知道每個文件的內容)
- 符號怎麼索引對象的, 對象怎麼存儲在image裏, 對象有幾種類型, 它們的底層存儲編碼是什麼, 如何查找/創建/讀取/更新/刪除它們
- 目前語言有多少包/多少符號/多少對像, 標準和實現定義部分主要有哪些(特別要了解能夠幫助進一步探索該系統的工具對象集和(就像知道ls, df, cd, more 這些基本命令))。
- 瞭解程序調度,體系結構: 知道系統是如何執行程序的, CPU是怎麼執行命令的, 以及內存是如何被利用的。
- 學會看對象在runtime裏的形態, 彙編, 反彙編它們, 知道Lisp層和Runtime層是如何交互的, 知道image被加載時和被保存時的形態
- 學會看對象在runtime裏的形態, 彙編, 反彙編它們, 知道Lisp層和Runtime層是如何交互的, 知道image被加載時和被保存時的形態
- 學會在該系統上寫程序, 知道有哪些庫可以利用, 學會調式你的程序。 (從這之後應該和學習其他語言沒什麼太大區別了。)
Lisp研究的目標
很多Lisp愛好者的終極目標就是Lisp Machine。 貌似有VM可以跑這些古老的運行在定製CPU上的系統,但我只看過一些視頻。 現代Common Lisp的許多方面可能都留有Lisp Machine的影子(個人覺得特別是CLIM的操作), 因此許多方面類似於OS也是很容易理解的。 作爲課題, 個人有幾個可選項,
- 從語言實現的角度出發, 繼續研究SBCL的編譯器和運行時環境, 參與SBCL的開發和port工作。
- 從語言應用的角度, 完善McCLIM, 增加GUI的風格, 修正bug, port到其他Backend和OS上, 改善目前開源CL缺乏穩定GUI的窘迫
- 從語言改善的角度, 將OS的許多特性移植到CL裏, 提高CL的安全,穩定和可操作性。(沒有必要侷限於語言標準的範疇?或產生新的方言)
- 從語言改善的角度, 將其他語言中優秀的特性移植到CL裏, 並去除CL中歷史遺留症, 讓它進化。(基於標準的基礎上,是否可以修改標準?或產生新的方言)