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