上個月,Python 之父 Guido van Rossum 在推特上轉發了一篇文章《The Origins of Python》,引起了我的強烈興趣。
眾所周知,Guido 在 1989 年聖誕節期間開始創造 Python,當時他就職於荷蘭數學和電腦科學研究學會(簡稱 CWI),曾參與設計與實現了一門用於教學的 ABC 語言。這段工作經歷以及 ABC 語言的某些設計思想對 Python 有著重要的影響。
文章標題是“Python 的起源”,文章作者 Lambert Meertens 是 Guido 在 CWI 時的導師,以同事親歷者的視角,講述 Python 從無到有的起源過程。這樣的文章我還未曾讀過,因此饒有興趣。
文章內容跟 Python 直接相關的部分並不多,作者花了較大篇幅介紹 ABC 專案的演變,討論了程式語言的設計(特別強調的是簡潔性 Simplicity)。
最引起我興趣的內容是:縮排語法的設計!
More striking is the use of indentation. Although it was common in programs written in ALGOL 60 or its descendants, such as Pascal, to use indentation as a typographical layout feature for clarifying the grouping of commands, this was an entirely optional presentation choice, made purely for the benefit of the human reader. In an article by P. J. Plauger entitled “Signal and Noise in Programming Languages,”16 we found the (then) radical idea to “have the compiler read the same signal as we human beings, and let the indenting control grouping,” a suggestion we followed with enthusiasm. Indentation to indicate that a suite of commands belong together subsequently became mandatory in B0 programs, a design choice that has been maintained throughout all iterations.17
——節選自《The Origins of Python》
簡單概括:當時在設計新的程式語言時,他們受到了一篇文章的強烈影響,決定僅採用縮排語法來控制程式碼塊的分組。核心思想是“have the compiler read the same signal as we human beings”,為了程式碼簡潔性及理解一致性,捨棄了其它的程式碼分組方案。
我極為推崇 Python 的強制縮排語法,曾寫過一篇《Python為什麼使用縮排來劃分程式碼塊?》介紹了這種設計的 8 個原因,但是,該文收到了大量的反對聲,因此,我又補寫了一篇《Python 的縮排是不是反人類的設計?》。
我知道自己的兩篇文章不足以說服那些討厭 Python 縮排的人,但是,如果有更多資料介紹這項設計的原因及思想來源的話,或許就能稍微地改觀某些人的看法,同時也提供給那些喜歡這項設計的人一些信心~
作為 ABC 語言的繼承者,Python 的縮排語法應該主要來源於它。因此,我決定沿著前文的線索,繼續挖掘它們設計縮排語法的起源。
上文提到的文章標題為《程式語言中的訊號與噪聲》(Signal and Noise in Programming Languages),發表於 1975 年的 ACM 年會論文集,作者 P.J. Plauger 是全球知名的電腦科學家、C/ C++技術專家以及 The Standard C Library、Standard C : A Reference 和 The Standard Template Library 等圖書的作者。
該篇文章想要區分程式語言的哪些語法是對讀者有用的訊號、哪些僅是無用的噪聲。文中提到了一個程式設計理論:“常說的東西應該言簡意賅(things which get said a lot should be concise)”。
由於程式碼經常要分組分塊,因此,“訊號與噪聲”一文將begin...end
及do...end
這兩種當時常見的程式碼分組語法批評為糟糕的設計。它不反對花括號“{...}”的語法設計,但是提出了一種更為激進的設計,也就是僅用縮排來控制程式碼分組(let the indenting control grouping)。
按我的理解,P.J. Plauger 建議我們移除程式語言中的噪聲。人們在閱讀程式碼時,可以直觀地根據程式碼的縮排層級將它們分組,因此縮排本身就是一種有意義的訊號,如果激進地讓機器也做到“所見即所得”的話,那甚至連“{...}”這種足夠言簡意賅的設計也不需要了。
P.J. Plauger 是個擅於總結程式設計風格/原則的人,他曾合作編寫過一本《The Elements of Programming Style》(譯本:程式設計格調),全書介紹了 70 多條最佳實踐和程式設計規則。
只不過,相比於他提出的那些經典的程式設計規則,“使用縮排來分組程式碼塊”不僅在 40 多年前是一條激進而少人接受的風格,它直到今天依然令某些人無法認同。
CWI 的團隊當初在設計 ABC 語言時,激進地採用了縮排作分組的設計。透過溯源那篇“古老的”文章,我們知道了這種設計不是他們突然蹦出的,而是有著某種設計思想的指導,同時這也意味著,Python 的縮排設計除了有“終身仁慈獨裁者(BDFL)”的個人偏好外,還隱含了這一層思想脈絡的淵源。
另外,《The Origins of Python》中還提供了兩個比《程式語言中的訊號與噪聲》更早的起源:
- 1965 年的 ISWIM 程式語言(“If you See What I Mean”的首字母縮寫)。它可能是有據可考最早使用縮排分組程式碼塊的語言(儘管它沒有實現),其設計者在《The Next 700 Programming Languages》中稱之為“Off-side rule”(越位規則)
- 1974 年唐納德·克努特(Donald Knuth,著名電腦科學家、圖靈獎獲得者,經典鉅著《計算機程式設計藝術》的作者)發表在 ACM 通訊的文章《 Structured Programming with Go To Statements》,他在暢想未來的程式語言時說:We will perhaps eventually be writing only small modules which are identified by name as they are used to build larger ones, so that devices like indentation, rather than delimiters, might become feasible for expressing local structure in the source language。
值得注意的是,唐納德提供的參考材料正是 1965 年 ISWIM 之父的文章《The Next 700 Programming Languages》,裡面收錄了多位大佬對於縮排的討論觀點。
受限於當時的計算機硬體及編輯器工具,以及考慮到印刷對程式碼排版的現實性影響,純縮排分組的程式碼確實可能會帶來一些麻煩。因此,這些程式設計界的先驅們僅僅是在大膽暢想未來的程式語言的語法,當時並沒有程式語言作出了實現。
從 1965 年的 ISWIM,到 1974 年唐納德的暢想,再到 1975 年 P.J. Plauger 激進的想法,再到 1980 年代 ABC 及 Python 的落地實現。20 多年的時間,說長確實是挺長了。
如今 2022 年即將過去,Python 已經度過了它的“而立之年”, 受這種設計思想影響的程式語言也遍地開花:據維基百科統計,有近 30 門語言使用“Off-side rule”。
儘管某些語言(如 Scala、Nemerle、Haskell)只是可選性或部分性支援,但這份列表意味著在花括號佔據統治地位的時代,縮排的星星之火依然迸發著頑強的生命力。暢想未來,我相信這份列表會加進更多語言,但願那時可以打破 Python 一枝獨秀的局面。
現在作一下總結吧。本文最先關注的是 Python 之父年輕時的導師的文章“Python 的起源”,但是我發現最吸引人的還是老生常談的縮排話題,於是文章主題轉向了“Python 的縮排語法的起源”。
不可否認,Python 的縮排語法屬於是較為大膽的程式設計風格,但換個角度,你也可以認為它很前衛,因為它本就起源於電腦科學家們在暢想未來的程式語言時的一種創意。
縮排語法簡潔、緊湊、清晰,它是營造出 Python 之美的最大功臣之一。人生苦短,我用 Python!
最後,如果你對 Python 其它語法的起源、為什麼這樣設計、跟其它語言的區別等等話題感興趣,歡迎關注“Python 為什麼”系列(請在 Github 上給顆小星星吧,喵~)