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),經過幾輪迭代後才逐漸形成某種數學圖景。