Dan Ingalls#
人物背景#
Dan Ingalls 被譽為 Smalltalk 之母——如果說 Alan Kay 是 Smalltalk 的父親,那麼 Ingalls 就是將它帶到世界上的人。他從第一個用 BASIC 寫成的 Smalltalk 實作開始,基於 Kay 的一頁筆記,參與了七代 Smalltalk 的實作,從最初的原型一直到現代的開源實作 Squeak。
- 原本是物理學家出身,在 Harvard 主修物理(1962-1966)
- 在 Stanford 修讀電機工程與計算機科學碩士,師從 Donald Knuth
- 從 Stanford 輟學後開始經營 profiler 軟體的生意
- 透過語音辨識專案的合作,進入 Xerox PARC,加入 Kay 的 Learning Research Group
- 在 PARC 發明了 BitBlt 操作,用於位圖圖形處理
- 獲得 ACM Grace Murray Hopper Award(1984)、ACM Software System Award(1987)
- 2002 年獲得 Dr. Dobb’s Excellence in Programming Award
- 受訪時為 Sun Microsystems 的 Distinguished Engineer,致力於 Lively Kernel 專案
程式啟蒙之路#
從發明家到程式設計師#
Ingalls 從小在地下室當發明家長大,物理是最接近他興趣的大學主修。在 Harvard 時接觸了 Fortran 課程和類比電腦,從此愛上程式設計。
- 在 Stanford 修了 Knuth 的程式量測(program measurement)研究生課程
- 開發了一個分析 Fortran 程式的 profiler 工具,並以此創業
- 這個 profiler 是取樣式分析器(sampling profiler)的先驅——在每個分支點插入計數器,加上計時器中斷來追蹤時間分布
Profiler 創業經歷#
- 將 profiler 帶到各地的服務中心(CDC、IBM)推銷
- 發現政府機構的 Fortran 使用者其實不在乎程式效率,他們真正想要的是證明電腦超載以申請新電腦
- 為 COBOL 開發了相同工具,可能是史上唯一用 COBOL 寫過 hash table 的人
- 這個工具賣得很好,演示時經常能省下比程式本身售價更多的費用
Ingalls 的 profiler 工作有一個重要創新:過去的程式量測都是以記憶體位置為單位報告結果,需要像「量子力學家」一樣才能解讀。他改為以原始碼的角度呈現結果,讓使用者一眼就能看出程式在哪裡花費最多時間。
互動式程式設計的熱情#
即時回饋的重要性#
Ingalls 的職業生涯有一個貫穿始終的主題:對互動式程式環境的熱情。
- 在語音辨識工作中,他在 Sigma 3 小型電腦上用 Fortran 和打卡機建立了一個完整的個人計算環境
- 接觸 APL 的互動式環境深受影響——即時看到結果回來的感覺,以及表達式求值的方式
- 認為 C/C++/Java 傳統雖然走向物件導向,但仍然是陳述式導向(statement-oriented)的,而表達式導向能讓數學活起來
「我認為任何能讓你獲得即時滿足感的東西,根據定義就會自我強化。」——Ingalls 解釋為什麼互動式環境如此重要。
沒有學 Lisp 反而是件好事#
Ingalls 到 Xerox 時沒有接觸過 Lisp,他認為這反而是好事:
- 如果已經熟悉 Lisp 這樣的系統,他永遠不會去費心處理物件
- 從物件的概念出發,再讓它變得互動和方便,這正是他的貢獻
- Alan Kay 說過 Lisp 和 Smalltalk 都太好了,好到「吃掉自己的孩子」——如果 Ingalls 認識 Lisp,Smalltalk 可能就是第一個被吃掉的孩子
Smalltalk 的七代演化#
Smalltalk-72:BASIC 上的原型#
- 從 Alan Kay 的一頁筆記開始,Ingalls 直接開始打程式碼
- 用 BASIC 實作,採用「麵包板」(breadboard)方式——先搭建結構,再讓它運作
- 第一個成功執行的程式是計算六的階乘
- 使用 reference counting 作為垃圾回收機制(後來證明不是最佳選擇,但無所謂)
Smalltalk-72 到 Smalltalk-76#
- Smalltalk-72 在 Nova 上有組合語言版本,後來移植到 Alto 上
- Smalltalk-72 有大量組合語言程式碼
- Smalltalk-76 的重大創新:byte-code 引擎,靈感來自 Peter Deutsch 的 Lisp byte-code 引擎
- 引入了 keyword syntax(後來成為 Smalltalk-80 語法的基礎)
- 類別和堆疊框架都變成了真正的物件,實現了自我描述
為什麼選擇 byte-code 而非直接編譯為機器碼?#
- 空間考量:byte-code 非常緊湊,當時 Alto 只有 96K(後來才有 128K)
- Ingalls 也純粹喜歡這個想法
- 受 Peter Deutsch 的 Lisp byte-code 引擎啟發
- 設想將 byte-code 引擎放入 Alto 的微碼(microcode)中,實現極致效能
Smalltalk-78 與 Smalltalk-80#
- Smalltalk-78:用 BitBlt 重寫了圖形核心,讓核心大幅縮小,首次在微處理器(8086)上執行
- Smalltalk-80:有了虛擬機規格,出版成書,但所有實作仍然用 C 或組合語言
- 直到 Squeak 才真正實現「用 Smalltalk 寫 Smalltalk」
Squeak:用 Smalltalk 寫 Smalltalk#
- Ingalls 離開業界後回來,想用 Smalltalk 做新專案
- 靈機一動:何不直接運行 Smalltalk 版本的直譯器,然後機械式地翻譯成 C?
- C 翻譯器只需要讓 parse tree 輸出為 C 語言即可
- 這樣就能在 Smalltalk 中修改虛擬機,測試後按下按鈕就能變成生產環境的直譯器
BitBlt 的發明#
問題本質#
- 螢幕是 1000x1000 像素的點陣,但記憶體是以字(word)為單位組織的
- 要在螢幕上移動圖形,需要處理跨越字邊界的位元操作
- 還有掃描線的二維問題——來源和目標可能有不同的每行字數
解決方案#
- BitBlt 本質上是一個長的移位器(shifter),從來源拾取字並放到目標位置
- 支援通用操作:移動、捲動、重疊視窗、像素混合
- Ingalls 先在 Smalltalk 中測試,再用組合語言實作,最後放入 Alto 的微碼中
- 在微碼中執行時,可以在記憶體全速下完成操作,隱藏所有遮罩和移位的延遲
BitBlt 對 Ingalls 而言更像是一個「影像」而非演算法——想像一個輪子在來源處拾取整個字,再放到目標處,只需要一次移位。這個心理圖像讓他看到了優雅的解法。
Lively Kernel 與核心哲學#
什麼是 Kernel?#
Ingalls 對「核心」(kernel)的定義:把足夠的東西組合在一起,使它能夠建構自身或建構其他有用的東西。
- Squeak:整個語言都是核心的一部分——有自己的編譯器和 byte-code 直譯器、完整的圖形系統(BitBlt)
- Lively Kernel:假設 JavaScript 和瀏覽器圖形已經存在,核心更小——只需要帶動圖形並建構小型計算環境
動態系統 vs. 靜態系統#
Ingalls 的核心哲學:從動態、彈性的系統開始,然後鎖定它,比從靜態系統開始再試圖加入動態特性要容易得多。
- 電腦在最底層就是完全可變的——全都是隨機存取記憶體,全都可程式化
- Web 程式設計就是反面教材:從文字標記語言開始,再加入 JavaScript 試圖讓它變動態
- 如果一開始就從動態圖形出發,要加上固定和可列印的功能會容易得多
「如果你有一個動態且可變的系統,要畫出邊界說『這裡面不能改』就容易多了。反過來,從不動態、不可變的東西開始,再試圖讓它變動態,那就困難多了。」
教育願景#
- Smalltalk 最初被設計為給「所有年齡的孩子」使用的語言
- 教育目標讓底層保持簡單,這反而啟發了更好的系統設計
- 四個深度學科:音樂、圖形、數學、文字——加上程式設計本身作為第五個學科
- 每個領域都有其「代數」:圖形有基本物件、疊加、平移、旋轉;音樂有音符、時間序列、和弦
測試與品質保證#
以即時滿足感為導向的測試#
- Ingalls 的測試方法:先追求最直接的滿足感
- 嘗試新東西時,想的是「什麼是第一個可達成的成功片段」
- 如果週末能讓它運作,那就是他要專注的部分
- 他承認在更正式的團隊程式設計環境中,會完全採用當前的團隊測試方式
Squeak 的可執行註釋#
- Squeak 程式碼中充滿了可執行的註釋
- 例如 BitBlt 測試:小程式會從螢幕上某處取一塊,做些操作,放回去——如果螢幕沒有任何變化,就表示正確
- 這種方式讓註釋本身就是測試
除錯方法#
最難追的 Bug#
- 最難追的是垃圾回收 bug——問題的表現往往在原因發生很久之後才出現
- 追蹤這種 bug 需要對「什麼能導致什麼」有深厚的直覺
- 他兒子曾頒給他一個「堅定除錯者獎」(Determined Debugger Award)
Smalltalk 除錯器的優勢#
- 可以在程式中任何地方停下來,查看所有變數的綁定
- 可以在上下文中執行程式碼片段、求值表達式
- 可以在任何堆疊框架中進行重大修改然後繼續執行
- 可以儲存整個系統狀態,傳給別人在不同機器上載入並繼續——跨平台完整保存狀態
對 print statement 除錯的看法#
- 如果有好的除錯器,誰會用 print statement?
- 與其把 print statement 放在某處然後印出它,不如直接去那裡看
- 但在 JavaScript 環境中,因為缺乏好的除錯器,他也做了不少 print statement 式的除錯
程式語言與工具觀點#
從未用過 C 或 C++#
- Ingalls 從未寫過 C 或 C++ 程式碼
- 主要使用 Fortran、BASIC、組合語言、Smalltalk、JavaScript
對型別系統的看法#
- 偏好非正式陣營——源於讓事物盡可能簡單的原始感覺
- 型別本質上是關於程式的斷言(assertions)
- 理想做法:讓系統盡可能簡單,甚至不需要標明型別;隨著系統變嚴肅,可以選擇性地加入型別
- 可以推論型別而非強制宣告,兩全其美
對正式驗證的看法#
- 從來不是他的工作範圍
- 傾向專注在架構層面,讓架構本身更容易做出斷言
- 如果架構乾淨,正式證明幾乎可以從閱讀程式碼中自然得出
團隊合作與領導#
在 PARC 的協作方式#
- Learning Research Group 是個小而緊密的團隊
- 每個人有各自的專長領域,彼此親近且偶爾會有「有建設性的混亂」
- 不太做結對程式設計,但有很多密集的結對除錯
- 協作方式:建一個不完整但能展示的框架,讓其他人很自然地知道他們的部分該怎麼接上
技術領導的建議#
- 第一要務是有清晰的願景——知道你要做什麼
- 當你能看到全局,就能立刻告訴卡住的人下一步是什麼
- 團隊成員能感受到領導者掌握全局,這對團隊有賦權效果
- 信任是關鍵——信任你合作的人,只在需要時才進行微管理
- 壞的微管理來自於擔心和不安全感
最好的老闆#
- Ingalls 認為他生涯中最好的老闆是 Alan Kay
- Kay 知道自己要什麼,但幾乎不說 Ingalls 該怎麼做
- 他是很好的技術批評者,但讓團隊有足夠的自主空間
- 他為團隊撐起了一把保護傘
對程式設計教育的看法#
應該從哪裡開始學?#
- 不認為一定要從組合語言學起,也不認為只有一種正確的學習路徑
- 「就像做藝術一樣,沒有唯一的方式」
- 建議:找到自己感興趣的領域(文字、數字、圖形、音樂),從那裡深入
- 立即的滿足感一直對他很有效
每個人都該學程式設計嗎?#
- 很難說每個人應該做什麼
- 但在讀寫能力的意義上,人們應該能夠邏輯思考
- 不會說每個人都該知道如何程式設計
- 日常生活中有很多類似程式設計的東西——按步驟做事的程序
除錯作為思維工具#
- 完全同意 Seymour Papert 在《Mindstorms》中的觀點:除錯是一種重要的智識工具
- 人們應該學會清晰地思考和質疑
- 「櫥櫃的門關不好,你會怎麼做?去檢查。看到螺絲鬆了,所以門歪了。」vs.「門不行了,叫人來修」——這中間有本質的差異
程式設計是否為年輕人的遊戲?#
- 不認為是
- 用學鋼琴做類比:他很晚才開始學鋼琴,別人說「應該趁年輕學」,但他發現年輕人不是學得更快,只是時間更多
- 程式設計也是一樣:年輕時有更多專注時間,但這不代表年齡是問題
- 現在有其他生活責任,確實削弱了那種專注的強度
- 與年輕同事合作很好——他花更多時間在目標和策略層面,年輕人則補足了深度鑽研的部分
對多樣性與創新的看法#
擁抱多元#
Ingalls 自稱是「擁抱多元的人」:
- 讓人們隨心所欲地去做——會有因為無知而浪費的部分,但自然選擇會整理出結果
- 試圖標準化、讓所有人朝同一方向走,反而壓抑了創造力
- Java 出現時,不僅讓其他物件導向語言慢下來,甚至讓整個動態語言程式設計都停滯了
對電腦科學教育的批評#
- 討厭看到電腦科學系認為自己的角色只是為業界準備人才
- 教學生按照業界的方式做事是完全錯誤的
- 應該教學生通用思維——跳出框架思考,探索其他課程
Ingalls 希望電腦科學界回歸第一原理,更多思考如何在智識空間中利用運算能力。邏輯程式設計、規則系統、人工智慧——這些領域在 1980 年前有大量進展,但後來幾乎被忽略了。以現代機器的算力,如果有一個小突破,就能做出不可思議的事情。
推薦書籍#
Ingalls 自認不是大量閱讀的人,但推薦了幾本:
- Val Schorre 的 META II 論文——在 Fortran 中實作了一個編譯器的編譯器
- LISP 1.5 手冊
- APL(雖然不覺得 Iverson 的書好讀,但語言本身值得花時間學習)
- Knuth 的基本資料結構相關著作
程式設計方式的演變#
- 現在有充裕的計算週期可以花費,可以安心地「浪費」週期來完成乾淨的程式碼
- 基本理念沒有改變:搞清楚要使用的核心是什麼,以及要達成的目標
- 開發方法:先追求效果——先看到畫面上的東西,這非常有激勵作用
- 然後如果需要效能優化,再 profiling
- 曾經在 Smalltalk 和 Squeak 中開發了很好的 profiler
Ingalls 把程式設計比作物理學——把程式當作可以觸摸和感受振動的東西。與 Knuth 在 TeX 上數學式、優雅的做法不同,Ingalls 的 Smalltalk 引擎更像是實驗性的、即興的(ad hoc),經過幾輪迭代後才逐漸形成某種數學圖景。