注:本文轉載自《程式設計師》
Paul Graham 是公認的“矽谷創業之父”,對於許多技術問題,他有自己獨到的見解。在本文中,他分享了何謂理想的程式語言。
我的朋友曾對一位著名的作業系統專家說他想要設計一種真正優秀的程式語言。那位專家回答,這是浪費時間,優秀的語言不一定會被市場接受,很可能無人使用,因為語言的流行不取決於它本身。至少,那位專家設計的語言就遭遇到了這種情況。
那麼,語言的流行到底取決於什麼因素呢?流行的語言是否真的值得流行呢?還有必要嘗試設計一種更好的語言嗎?如果有必要的話,怎樣才能做到這一點呢?
為了找到這些問題的答案,我想我們可以觀察黑客,瞭解他們使用什麼語言。程式語言本來就是為了滿足黑客的需要而產生的,當且僅當黑客喜歡一種語言時,這種語言才能成為合格的程式語言,而不是被當做“指稱語義”(denotational semantics)或者編譯器設計。
流行的祕訣
沒錯,大多數人選擇某一種程式語言,不是因為這種語言有什麼獨特的特點,而是因為聽說其他人使用這種語言。但是我認為,外界因素對於程式語言的流行其實並沒有想象中那麼大的影響力。我倒是覺得,問題出在對於什麼是優秀程式語言,黑客的看法與大多數的語言設計者不一樣。
黑客的看法其實比語言設計者的更重要。程式語言不是數學定理,而是一種工具,為了便於使用,它們才被設計出來。所以,設計程式語言的時候必須考慮到人類的長處和短處,就像設計鞋子的時候必須符合人類的腳型。如果鞋子穿上去不舒服,無論它的外形多麼優美,多麼像一件藝術品,你也只能把它當做一雙壞鞋。
大多數程式設計師也許無法分辨語言的好壞。但是,這不代表優秀的程式語言會被埋沒,專家級黑客一眼就能認出它們,並且會拿來使用。雖然他們人數很少,但就是這樣一小群人寫出了人類所有的優秀軟體。他們有著巨大的影響力,他們使用什麼語言,其他程式設計師往往就會跟著使用。老實說,很多時候這種影響力更像是一種命令,對於其他程式設計師來說,專家級黑客就像自己的老闆或導師,他們說哪種語言好用,自己就會乖乖地跟進。
專家級黑客的看法不是決定一種語言流行程度的唯一因素,某些古老的軟體(Fortran 和 Cobol 的情況)和鋪天蓋地的廣告宣傳(Ada 和 Java 的情況)也會起到作用。但是,我認為從長期來看,專家級黑客的看法是最重要的因素。只要有了達到“臨界數量”(critical mass)的最初使用者和足夠長的時間,一種語言就可能會達到應有的流行程度。而流行本身又會使得這種優秀的語言更加優秀,進一步拉大它與平庸語言之間的好壞差異,因為使用者的反饋總是會導致語言的改進。你可以想一下,所有流行的程式語言從誕生至今的變化有多大。Perl 和 Fortran 是極端的例子,但是甚至就連 Lisp 都發生了很大的變化。
所以,即使不考慮語言本身的優秀是否能帶動流行,我想單單流行本身就肯定會使得這種語言變得更好,只有流行才會讓它保持優秀。程式語言的最高境界一直在發展之中。雖然語言的核心功能就像大海的深處,很少有變化,但是函式庫和開發環境之類的東西就像大海的表面,一直在洶湧澎湃。
當然,黑客必須先知道這種語言,才可能去用它。他們怎麼才能知道呢?就是從其他黑客那裡。所以不管怎樣,一開始必須有一群黑客使用這種語言,然後其他人才會知道它。我不知道“一群”的最小數量是多少,多少個黑客才算達到“臨界數量”呢?如果讓我猜,我會說 20 人。如果一種語言有 20 個獨立使用者,就意味著有 20 個人是自主決定使用這種語言的,我覺得這就說明這種語言真的有優點。
達到這一步並非易事。如果說使用者數從 0 到 20 比從 20 到 1000 更困難,我也不會感到驚訝。發展最早的 20 個使用者的最好方法可能就是使用特洛伊木馬:你讓人們使用一種他們需要的應用程式,這個程式碰巧就是用某種新語言開發的。
外部因素
我們得先承認,確實有一個外部因素會影響到語言的流行。一種語言必須是某一個流行的計算機系統的指令碼語言(scripting language),才會變得流行。Fortran 和 Cobol 是早期 IBM 大型機的指令碼語言。C是 Unix 的指令碼語言,後來的 Perl 和 Python 也是如此。Tcl 是 Tk 的指令碼語言,Visual Basic 是 Windows 的指令碼語言,(某種形式的)Lisp 是 Emacs 的指令碼語言,PHP 是網路伺服器的指令碼語言,Java 和 JavaScript 是瀏覽器的指令碼語言。
程式語言不是存在於真空之中。“程式設計”其實是及物動詞,黑客一般都是為某個系統程式設計,在現實中,程式語言總是與它們依附的系統聯絡在一起的。所以,如果你想設計一種流行的程式語言,就不能只是單純地設計語言本身,還必須為它找到一個依附的系統,而這個系統也必須流行。除非你只想用自己設計的語言取代那個系統現有的指令碼語言。
這種情況導致的一個結果就是,無法以一種語言本身的優缺點評判這種語言。另一個結果則是,只有當一種語言是某個系統的指令碼語言時,它才能真正成為程式語言。如果你對此很吃驚,覺得不公平,那麼我會跟你說不必大驚小怪。這就好比大家都認為,如果一種程式語言只有語法規則,沒有一個好的實現(implementation),那麼它就不能算完整的程式語言。這些都是很正常很合理的事情,程式語言本來就該如此。
當然,程式語言本來就需要一個好的實現,而且這個實現必須是免費的。商業公司願意出錢購買軟體,但是黑客作為個人不會願意這樣做,而你想讓一種語言成功,恰恰就是需要吸引黑客。
程式語言還需要有一本介紹它的書。這本書應該不厚,文筆流暢,而且包含大量優秀的範例。布賴恩·柯尼漢和丹尼斯·裡奇合寫的《C程式設計語言》(C Programming Language)就是這方面的典範。眼下,我大概還能再加一句,這一類書籍之中必須有一本由O’Reilly 公司出版發行。這正在變成是否能吸引黑客的前提條件了。
程式語言還應該有線上文件。事實上,線上文件可以當做一本書來寫,但是目前它還無法取代實體書。實體書並沒有過時,它們讀起來很方便,而且出版社對書籍內容的稽核是一種很有用的質量保證機制(雖然做得很不完美)。書店則是程式設計師發現和學習新語言的最重要的場所之一。
簡潔
假定你的語言已經能夠滿足上面三項條件——一種免費的實現,一本相關書籍,以及語言所依附的計算機系統——那麼還需要做什麼才能使得黑客喜歡上你的語言?
黑客欣賞的一個特點就是簡潔。黑客都是懶人,他們同數學家和現代主義建築師一樣,痛恨任何冗餘的東西或事情。有一個笑話說,黑客動手寫程式之前,至少會在心裡盤算一下哪種語言的打字工作量最小,然後就選擇使用該語言。這個笑話其實與真實情況相差無幾。就算這真的是個笑話,語言的設計者也必須把它當真,按照它的要求設計語言。
簡潔性最重要的方面就是要使得語言更抽象。為了達到這一點,首先你設計的必須是高階語言,然後把它設計得越抽象越好。語言設計者應該總是看著程式碼,問自己能不能使用更少的語法單位把它表達出來。如果你有辦法讓許多不同的程式都能更簡短地表達出來,那麼這很可能意味著你發現了一種很有用的新抽象方法。
不要覺得為使用者著想就是讓他們使用像英語一樣又長又囉唆的語法。這是不正確的做法,Cobol 就是因為這個毛病而聲名狼藉。
如果你讓黑客像下面這樣求和:
add x to y giving z
而不是寫成:
z=x+y
那麼你就是在侮辱黑客的智商,或者自己作孽了。
簡潔性是靜態型別語言的力所不及之處。不考慮其他因素時,沒人願意在程式的頭部寫上一大堆的宣告語句。只要計算機可以自己推斷出來的事情,都應該讓計算機自己去推斷。舉例來說,hello-world 本應該是一個很簡單的程式,但是在 Java 語言中卻要寫上一大堆東西,這本身就差不多可以說明 Java 語言設計得有問題了。
單個的語法單位也應該很簡短。Perl 和 Common Lisp 在這方面是兩個不同的極端。Perl 的語法單位很短,導致它的程式碼可以擁擠得讓人無法理解,而 Common Lisp 內建運算子的名稱則長得可笑。Common Lisp 的設計者們可能覺得文字編輯器會幫助使用者自動填寫運算子的長名稱。但是這樣做的代價不僅是增加了打字的工作量,還包括提高了閱讀程式碼的難度,以及佔用了更多的顯示器空間。
可程式設計性(Hackability)
對黑客來說,選擇程式語言的時候,還有一個因素比簡潔更重要,那就是這種語言必須能夠幫助自己做到想做的事。在程式語言的歷史上,防止程式設計師做出“錯誤”舉動的措施多得驚人。這是語言設計者很自以為是的危險舉動,他們怎麼知道程式設計師該做什麼不該做什麼?我認為,語言設計者應該假定他們的目標使用者是一個天才,會做出各種他們無法預知的舉動,而不是假定目標使用者是一個笨手笨腳的傻瓜,需要別人的保護才不會傷到自己。如果使用者真的是傻瓜,不管你怎麼保護他,他還是會搬起石頭砸自己的腳。你也許能夠阻止他引用另一個模組中的變數,但是你沒法防止他日日夜夜不知疲倦地寫出結構混亂的程式去解決完全錯誤的問題。
優秀程式設計師經常想做一些既危險又令人惱火的事情。所謂“令人惱火”,我指的是他們會突破設計者提供給使用者的外部語義層,試著控制某些高階抽象的語言內部介面。比如,黑客喜歡破解,而破解就意味著深入內部,揣測原始設計者的意圖。
你應該敞開胸懷,歡迎這種揣測。對於製造工具的人來說,總是會有使用者以違揹你本意的方式使用你的工具。如果你製造的是程式語言這樣高度組合的系統,那就更是如此了。許多黑客會用你做夢也想不到的方式改動你的語法模型。我的建議就是,讓他們這樣幹吧,而且應該為他們創造便利,儘可能多地把語言的內部暴露在他們面前。
其實,黑客並不會徹底顛覆你的工具,在一個大型程式中,他可能只是對語言改造一兩個地方。但是,改動多少地方並不重要,重要的是他能夠對語言進行改動。這可能不僅有助於解決一些特殊的問題,還會讓黑客覺得很好玩。黑客改造語言的樂趣就好比外科醫生擺弄病人內臟的樂趣,或者青少年喜歡用手擠破青春痘的那種感覺。至少對男生來說,某些型別的破壞非常刺激。針對青年男性讀者的 Maxim 雜誌每年出版一本特輯,裡面一半是美女照片,另一半是各種嚴重事故的現場照片。這本雜誌非常清楚它的讀者想看什麼。
一種真正優秀的程式語言應該既整潔又混亂。“整潔”的意思是設計得很清楚, 核心由數量不多的運算子構成,這些運算子易於理解,每一個都有很完整的獨立用途。“混亂”的意思是它允許黑客以自己的方式使用。C語言就是這樣的例子,早期的 Lisp 語言也是如此。真正的黑客語言總是稍微帶一點放縱不羈、不服管教的個性。
優秀的程式語言所具備的功能,應該會使得言必稱“軟體工程”的人感到非常不滿、頻頻搖頭。與黑客語言形成鮮明對照的就是像 Pascal 那樣的語言,它是井然有序的模範,非常適合教學,但是除此之外就沒有很大用處了。
一次性程式
為了吸引黑客,一種程式語言必須善於完成黑客想要完成的各種任務。這意味著它必須很適合開發一次性程式。這一點可能出乎很多人的意料。
所謂一次性程式,就是指為了完成某些很簡單的臨時性任務而在很短時間內寫出來的程式。比如,自動完成某些系統管理任務的程式,或者(為了某項模擬任務)自動生成測試資料的程式,以及在不同格式之間轉化資料的程式等。令人吃驚的是,一次性程式往往不是真的只用一次,就像二戰期間很多美國大學造的一大批臨時建築後來都成了永久建築。許多一次性程式後來也都變成了正式的程式,具備了正式的功能和外部使用者。
我有一種預感,最優秀的那些大型程式就是這樣發展起來的,而不是像胡佛水壩那樣從一開始就作為大型工程來設計。一下子從無到有做出一個大專案是一件很恐怖的事。當人們接手一個巨型專案時,很容易被它搞得一蹶不振。最後,要麼是專案陷入僵局,要麼是做出來一個規模小、效能差的東西。你想造一片鬧市,卻只做出一家商場;你想建一個羅馬,卻只造出一個巴西利亞;你想發明C語言,卻只開發出 Ada。
開發大型程式的另一個方法就是從一次性程式開始,然後不斷地改進。這種方法比較不會讓人望而生畏,程式在不斷的開發之中逐漸進步。一般來說,使用這種方法開發程式,一開始用什麼程式語言,就會一直用到最後,因為除非有外部政治因素的干預,程式設計師很少會中途更換程式語言。所以,我們就有了一個看似矛盾的結論:如果你想設計一種適合開發大型專案的程式語言,就必須使得這種語言也適合開發一次性程式,因為大型專案就是從一次性程式演變而來的。
Perl 就是一個鮮明的例子。它不僅僅設計成適合開發一次性程式,而且它本身就很像一次性程式。最初的 Perl 只是好幾個生成表格的工具收集在一起而已。後來程式設計師用它寫一次性程式,當那些程式逐漸發展壯大後,Perl 才隨之發展成了一種正式的程式語言。到了 Perl 5,這種語言才適合開發重要的程式,但是在此之前它已經廣為流行了。
什麼樣的語言適合寫一次性程式?首先,它必須很容易裝備。一次性程式是你只想在一小時內寫出來的程式,所以它不應該耗費很多時間安裝和配置,最好已經安裝在你的電腦上了。它必須是想用就用的。C語言可以想用就用,因為它是作業系統的一部分;Perl 可以想用就用,因為它本來就是一種系統管理工具,作業系統已經預設安裝它了。
很容易裝備不僅僅指很容易安裝或者已經安裝,還指很容易與使用者互動。一種有命令列介面、可以實時反饋的語言就具有互動性,那些必須先編譯後使用的語言就不具備互動性。受歡迎的程式語言應該是前者,具有良好的互動性,可以快速得到執行結果。
一次性程式的另一個特點就是簡潔。對黑客來說,這一點永遠有吸引力。如果考慮到你最多隻打算在這個程式上耗費一個小時,這一點就更重要了。
Paul Graham
矽谷創業之父,經歷頗為傳奇。他大學在康奈爾大學主修哲學,研究生在哈佛大學主攻人工智慧,博士期間又去哈佛藝術系旁聽。拿到博士學位後,先後進入羅德島設計學院和佛羅倫薩美術學院學習繪畫,夢想成為畫家。1995 年,他與史上第一個蠕蟲病毒“莫里斯蠕蟲”的製作者 Robert Morris 開發出世界上第一個通過網際網路使用的軟體—Viaweb,該軟體後來被雅虎以 4900 萬美元兼併,並改名為 Yahoo Store。結束在雅虎的任職後,他將自己對於技術和創業的觀點寫成系列文章,由O’Reilly 結集出版,取名為《黑客與畫家》。2005 年,他與 Morris 等人合夥成立了Y Combinator(簡稱 YC),它既是一個創業公司的孵化器,也是一個教導員,還是一個與投資人聯絡的中介。到目前為止,從 YC“畢業”的創業公司共有 200 多家,已經失敗的公司不到 20%,遠低於 90% 的業內平均水平。這些 YC 學員成為新一代矽谷創業公司的主流,他們組成了一張不斷壯大的關係網,有人稱其為“YC 匪幫”。
本文節選自 Paul Graham 的文集《黑客與畫家》,主要介紹黑客及優秀程式設計師的愛好和動機,討論黑客成長、黑客對世界的貢獻以及程式語言和黑客工作方法等話題。中文版將由人民郵電出版社北京圖靈文化發展有限公司出版,特此感謝圖靈公司授權。