Erlang之父Joe Armstrong訪談:程序調試與啤酒
以啤酒收取程序調試報酬
Seibel:你是如何開始學習編程的?是從什么時候開始的?
Armstrong:是從中學時開始的。我出生于1950年,上中學那會兒還沒有幾臺計算機。到了中學最后一年,那年我應該是17歲,我們當地的議會得到一臺大型計算機,好像是IBM的。我們可以在上面寫Fortran程序。通常,我們在編碼紙上寫好程序,然后發出去。一個星期后,等編碼紙和穿孔卡拿回來的時候還必須確認一下。但是制作穿孔卡的人總會出點錯,所以可能要反復1~2次才能弄好。最后這些穿孔卡就可以送到計算機中心了。
卡片進入計算機中心后會再拿回來,因為Fortran編譯器會在程序中出現第一個句法錯誤的地方停下來,后面的程序就都不處理了。你的第一個程序似乎需要3個月才能跑通。我認識到,不能每次只送一個程序,應當并行地開發多個單一子例程并且一次都送去。我記得寫過一個顯示國際象棋棋盤的小程序,用打印機繪制出來。但是因為中間等待的時間太煩人了,我不得不把所有的子例程都當做并行的任務一次寫完。
Seibel:你學的是物理學,是從什么時候開始轉向編程的?
Armstrong:嗯,有一些本科生的課程需要編寫程序,而我又特別喜歡編程。我還非常善于調試程序。如果別人程序出了問題,我就會去調試別人的程序。標準調試的開價是一杯啤酒。也可能提價,還有兩杯啤酒、三杯啤酒的問題。
Seibel:在給他們調試程序時,是以他們必須給你買多少杯啤酒而論的,對嗎?
Armstrong:對,等我修復了程序時他們要給我買啤酒。我在讀程序的時候總是在想:“他們為什么要這樣寫程序呢,太復雜了。”我會重新編寫并簡化程序。看到人們編寫復雜的代碼我感到很吃驚。有些問題用幾行代碼就能解決,但是他們要寫上幾十行。我有點好奇,他們為什么看不到簡單的方法呢。而我就頗為擅長采取簡單的方法。
我真正開始編程是拿到第一個學位并打算讀博士學位的時候。我開始讀高能物理博士學位并加入了那里的氣泡室小組,他們有一臺計算機。那是一臺DDP-516,是Honeywell公司的。我可以獨自一人使用它。它是穿孔卡式的,但是可以在上面直接運行程序,只要把穿孔卡放進去,按一下按鈕,答案刷地一下就出來了。我特別喜歡那臺計算機。我在上面編寫了一個小象棋程序。
那時的實際磁心存儲器是由婦女編織而成的,能夠看到磁心和一塊塊的小磁鐵和穿進穿出的線路。它的價格高得驚人,有一個大約10MB的磁盤驅動器,上面有20個小底板,大約15公斤重。它還配了一個電傳文本的界面,可以在上面輸入程序。
后來又出現了“玻璃電傳打字終端”,那是最早的視頻顯示器設備,可以在上面輸入并編輯程序。我覺得這太神奇了,再也不需要穿孔卡了。我記得當時和計算機管理員說:“要我說,將來有一天人人都會有這樣一套機器。”他說道:“我看你瘋了,Joe,你真是瘋了!”“為什么不可能呢?”“這些東西貴得離譜。”
正是從那時我真正開始學習編程了。當時我的導師對我說:“你不應該再讀物理學博士了,改行吧。你熱愛計算機,應當搞計算機。”我說道:“不,不,不。我不能半途而廢。”但實際上他的話是對的。
不同尋常的工作經歷
Seibel:那你拿到博士學位了嗎?
Armstrong:沒有。我沒錢了,所以沒有讀完。我后來去了愛丁堡大學。此前在讀物理的時候我們常常到物理系圖書館去學習。在圖書館的角落里有一些計算機科學書籍。有一些棕色封底的雜志叫做《機器智能》,一共有4期,是愛丁堡大學的機器智能系編輯出版的。我學的是物理學,但我卻渴望閱讀這些雜志,并且在想:“真是太有趣了。”DonaldMichie那時擔任愛丁堡大學機器智能系的主任,我給他寫了封信,說我對這種東西非常感興趣,問他那里有沒有工作可做。他給我回了信,說目前還沒有,不過無論如何,他很想和我見一面,看看我是什么樣的人。
幾個月后我接到一個電話,也可能是一封信,是Michie的。他說:“我周二去倫敦,我們見一面如何?我要乘火車回愛丁堡,你能來車站嗎?”我去了車站,見到Michie,他說:“嗯,不能在這兒面試—我們去找個酒吧。”于是我們到一家酒吧聊了聊。過了沒多久又收到他的一封信,說:“在愛丁堡大學有一份研究工作,你申請一下吧。”于是我成了DonaldMichie的研究助理并去了愛丁堡大學。我就這樣從物理學轉到了計算機。
Michie在二戰期間曾經和圖靈在布萊切利公園(BletchleyPark)(編者注:二戰爆發前,英國在距離倫敦不遠的布萊切利公園設置了國家密碼破譯機構,許多破譯員在那里工作,破解德國電報密碼)一起工作過,拿到了圖靈所有的論文。我在圖靈圖書館有一張書桌,周圍也全都是圖靈的論文。我在愛丁堡大學待了一年。此后由于數學家JamesLighthill的原因,愛丁堡大學都有點維持不下去了。Lighthill受雇于政府,前往愛丁堡大學調查人工智能。他回去后說道:“那個地方什么有商業價值的東西也弄不出來。”
說得就像一個巨大的兒童游戲區。我是英國機器人學會的創始成員,我們都認為這個工作意義重大。但是撥款機構卻說:“機器人!這是什么東西!我們不打算在這上面投入資金了。”我記得那是1972年前后,所有的資金來源都枯竭了,大家都說:“嗯,在這里度過的時光非常美好,但現在最好還是找點別的事情做吧。”
于是我又回去從事物理學工作了。我到了瑞典,在EISCAT科學協會得到一份物理學程序員的工作。我的上司來自IBM,年紀比我大,他想要上頭給出一份規格說明書,這樣他就可以拿去實行。我們曾經討論過這個問題。他說:“如果沒有任務說明,也沒有規格說明,這樣的工作太糟糕了。”我說:“嗯,如果沒有任務說明,那才是一個好任務。因為你可以按照自己喜歡的方式來完成。”一年后我的上司離職了,我接替了他的工作,擔任首席設計師。
我為他們設計了一個系統,可以稱為應用操作系統,那是一個在普通操作系統上運行的系統。那個時候計算機的價格已經比較合理了。我們有一些NORD-10計算機,是挪威制造的—我覺得他們這種型號的計算機想要進入PDP-11的市場。
我在那里工作了將近4年。接著在瑞典空間研究中心得到一份工作,構建了另外一個應用操作系統,用于控制瑞典發射的名為“海盜”的第一顆衛星。那是一個有趣的項目,不過我忘了那臺計算機的名字了,只記得它克隆的是Amdahl公司的計算機。那上面還只有行編輯器,沒有全屏幕編輯器。所有的程序都只能放到一個目錄下面。文件名是10個字母,擴展名是3個字母。還有一個Fortran編譯器或匯編語言編譯器,全部東西就是這些了。
有趣的是,現在回頭想想,我不認為當今這些小玩意會讓你的生產率更高。比如說分層文件系統,它怎么可能讓生產率更高呢?很多程序開發方式是在腦海中形成的。我認為在那些簡單的系統上工作可以強制你規范地進行思考。如果沒有目錄系統,就只能把所有的文件都放到一個目錄下面,你只能變得相當規范。如果沒有修訂控制系統,你也只能變得相當規范。如果自己做的事情能夠規范起來,那我覺得分層文件系統和修訂控制系統也就沒什么可取之處了。它們解決的問題并不能從本質上解決你的問題。如果多人一起工作,它們可能會讓事情容易一些。但對個人來說,我看不出來有什么差別。
另外,我覺得我們現在因為選擇過多而不堪重負。我的意思是,那時候我只能使用Fortran。甚至連Shell腳本也沒有。只有可以運行程序的批處理文件,編譯器,還有就是Fortran。如果確實需要的話,還可能有匯編語言編譯器。不需要痛苦地做出選擇。今天年輕的程序員肯定會感到很不舒服,面對20種編程語言和幾十種框架,該如何選擇,真是無所適從。我們那時沒有這些難以選擇的地方。只要開始做就行了,因為使用什么語言、什么工具都已經是定下來的。不需要考慮該做些什么,只管做就行了。
打開黑盒的重要性
Seibel:另外一個差別是現在也無法徹底了解整個系統了。也就是說不僅僅是要做出很多選擇,而且在選擇要使用哪些黑盒的時候,還不一定完全理解黑盒的工作方式。
Armstrong:是啊,如果這些大黑盒不能正常工作,必須做出修改,我覺得自己把所有的內容都從頭開始編寫一次會更容易些。做不到軟件復用,真是太糟糕了。
Seibel:但是如果把所有這些黑盒都打開,看看里面有什么,看看它們的工作方式,再確定如何對它們做一點改造來滿足自己的需要。你覺得這樣做確實是可行的嗎?
Armstrong:這些年我犯了一些人們常犯的錯誤,那就是沒有打開黑盒。有時候想一想,覺得這個黑盒無法理解,難度太大,所以不想打開它。我曾經打開過1~2個黑盒。有一次我需要做一個窗口系統,為Erlang做一個圖形系統,我在想:“嗯,就在XWindows上運行吧。”XWindows是什么呢?它是一個套接字,上面跑著協議。只要打開套接字,往里面注入這些消息就可以了。為什么要用庫呢?Erlang是基于消息的。整體指導思想是向其他東西發出消息,讓它們執行操作。嗯,XWindows中的指導思想則是,有一個窗口,向窗口發送消息,再由窗口執行操作。如果在窗口中執行操作,它會把消息回送給你。這非常像Erlang。但是XWindows的編程方式是運用回調庫—如果出現了這個情況就調用這個函數。這不是Erlang的思考方式。Erlang的思考方式是,給某個東西發送消息,讓它做一些事情。所以,等一下,把其中的庫去掉吧,直接和套接字對話。
猜猜結果會怎么樣?非常簡單。X協議收到了一些消息,我不知道具體是多少條,也許是100條、80條,大致就是這么多。但實際上只需要其中的20條就能完成有用的工作了。把這20條消息映射到Erlang術語上,變個小魔術,然后可以向窗口直接發送消息,它們就開始執行動作了。這樣做的效率也很高。但界面不是很好,因為我沒有把太多的精力用到圖形和藝術標準上。如果為了讓界面再美觀一些,要做的工作還很多。但是不管怎么說,實際上并不難。
另外一個例子是我做的排版系統,我打開的抽象邊界是PostScript。到了邊界的地方你會想:“我不想越過這個邊界。”因為你會認為邊界里面的東西極其復雜。但是我再次發現,它實際上是很簡單的。那是一種編程語言,一種不錯的編程語言。抽象邊界很容易穿越,而一旦穿越,會有很多收益。
在出版我那本Erlang編程書時,出版社說:“我們有畫圖工具。”但是畫圖工具真的很難精確地對準箭頭,所以我不喜歡那些工具。而且畫圖的時候手也很難受。我想:“編寫一個生成PostScript的程序,然后在‘這里畫個圓圈、那里畫個箭頭’,讓程序正常運轉起來,這樣一比,編程花的時間并不長。”編寫程序需要幾個小時。以所見即所得的方式畫圖也需要這么長時間。只是自己編寫程序還有兩個好處。你的手不會難受,而且即使把圖形放大一萬倍,看到的箭頭也是對得整整齊齊的。
我并不是說剛入行的程序員應當把所有這些抽象的東西都打開。我的意思是,一定要考慮是否可以打開它們。不要完全放棄這個想法。看看直接到達的途徑是不是比包裝后的途徑要快一些,這是值得一看的。一般來說,如果購買軟件或是使用其他人的軟件,一定要充分考慮還需要花很長時間來加工這套軟件,因為它和你想要的不完全一樣。軟件的執行方式有微妙的差別,而這個差別可能需要很長時間來解決。
編程這些年的變化
Seibel:同剛開始編程時相比,你在看待該如何編程的問題上最大的變化是什么?
Armstrong:我認為編程方式中的最大變化與硬件無關。顯然,現在的計算機速度要快得多,功能要強大得多,但是人的大腦比最好的軟件工具還要強大一百萬倍。我在編寫程序的時候,幾天之后會突然說:“程序中有一個錯誤—如果這樣、那樣、那樣、這樣的話,程序就要崩潰了。”然后我去看了代碼,確實如此。此前一點征兆也沒有。你能告訴我哪一個開發系統能夠做到這一點嗎?作為一個程序員,我所發生的變化是內心思想的變化。
我認為在經過多年的編程之后會有兩個變化。一個變化是,在年輕的時候,我會不停地寫程序,直到完成。當程序完成后,我就不再管它了。程序寫好了,完工了。然后我會突然領悟:“啊!搞錯了!真是笨蛋!”我會重新編寫程序,后來再次發現:“噢,程序是錯的。”于是又重新編寫。
我記得當時有這樣一個想法:“先不要動手寫代碼,把這些東西都想好,這樣做不是很好嗎?”如果我不寫代碼就能獲得那番領悟,不是很好嗎?我認為現在可以做到這一點了。那20年可以算作是學習如何編程的時期。現在知道該如何編程了。我以前通過實驗來學習編程。現在我知道該如何編程了,不需要再做實驗了。
偶爾,我也得做一些很小的實驗,比如編寫一些非常小的程序來回答某個問題。我會把事情想清楚,等到開始編程的時候,這些程序就可以或多或少地像我預計的那樣運行起來了,因為之前我已經想清楚了。這也意味著要花很長時間。編寫程序、有所醒悟、重新編寫。這樣可能需要花上一年的時間來寫程序。所以我現在可能不這樣做,而是先思考上一年。我不會再做那種簡單的輸入工作。
這是第一個變化。出現的第二個變化是直覺。在年輕的時候,我會通宵地寫程序,干到凌晨4點鐘,精疲力盡,那是男子漢氣概的編程,一個小時接著一個小時,不停地編寫代碼。即使情況不好我也堅持不懈,總要讓代碼能夠跑起來。即使沒有直覺,我也要繼續編程。
我得到的教訓是,在疲憊的時候編寫的程序都是垃圾,第二天就要把它們都扔掉了。20年前,就算強烈地感到事情不對勁、代碼中有錯誤時,我也會繼續編程。這些年來我注意到,真正好的代碼是我完全進入狀態的時候編寫的,時間不知不覺地過了,而我甚至沒有在考慮程序,只是很放松地坐在那里,輸入這些東西,看著自己輸入的東西出現在屏幕上。這樣的代碼會很不錯。如果你不能集中注意力,弄出來的東西會說:“不行,不行,這兒錯了,那兒也錯了。”可我在多年前并沒有注意到這一點。寫出來的代碼都被扔掉了。現在,如果覺得不行,我就不再編程了。“不能再寫了。”這是我根據經驗得到的,停下來,不要再寫代碼了。不要再處理這個問題了。干點別的。
我在上學的時候很擅長數學之類的課程,所以在想:“噢,我是一個按照邏輯思考的人。”但是我參加心理測試時,在直覺上得了高分,而邏輯思考方面的分數卻有點低。不是很低,我還是可以做數學這類的題目,我相當擅長。但正是因為我擅長數學,所以我過去認為科學是關于邏輯和數學的。我現在就不會這樣說了。我要說科學也有很多直覺,根據直覺能夠知道什么是正確的。
Seibel:你現在在編碼之前會花更長的時間思考,那么在思考階段會做些什么呢?
Armstrong:噢,我會記些筆記,我不僅僅是在思考。在紙上隨便寫點什么。我可能不會寫很多代碼。如果你密切注意我的活動,會發現我大部分時間都在思考,偶爾寫點什么。另外一件對解決問題非常重要的事情是問問我的同事:“你將如何解決這個問題?”你找到他們,說:“我不知道應當采取這種方式還是那種方式。必須在A和B之間做出選擇。”然后你向他們描述A和B,等講到一半的時候,你會說:“啊,是B。謝謝你們。非常感謝。”這樣的事情發生過很多次。
你需要這樣一塊智能白板,如果你只是獨自一人在一塊白板上寫寫畫畫,是得不到反饋的。但是如果面對的是人,你會在白板上向他們解釋替代方案,他們也會加入討論,提出一點建議。然后突然間你就知道答案是什么了。對我來說沒有涉及到代碼編寫。但是和處理同樣問題的同事進行交談是非常有價值的。
原文鏈接:http://www.programmer.com.cn/4935/
【編輯推薦】