上海基诺彩票中奖号码

English [en]   espa?ol [es]   fran?ais [fr]   日本語 [ja]   português do Brasil [pt-br]   русский [ru]   Shqip [sq]   укра?нська [uk]   簡體中文 [zh-cn]  

這是針對英文原版頁面的中文翻譯。

我的Lisp經歷和GNU Emacs的開發

(Richard Stallman在國際Lisp大會上的談話記錄,2002年10月28日)

由于我通常的演講都和Lisp無關,我今天講它們不合適。所以我將不得不即興發揮。我的職業生涯做了太多Lisp相關的工作,因此我還是可以講一些有趣的事情的。

我最早關于Lisp的經歷是在高中時讀了Lisp 1.5的手冊。其中的思想讓我腦洞大開:怎么還有這樣的計算機語言!我第一次有機會做Lisp相關的工作是在當哈佛新生的時候,我為PDP-11處理器編寫了一個Lisp解釋器。那是一個非常小的機器—大概只有8k的內存—我設法用1000條以內的指令編寫了那個解釋器。這樣我還有一點數據空間。這是在我看到真正做系統工作的軟件之前。

當我在MIT開始工作時,我和JonL White一起真正開始實現Lisp語言。我不是被JonL,而是被Russ Noftsker招到人工智能實驗室的,這一點最諷刺,想想接下來發生的事—他一定真的后悔有那一天了。

在1970年代,我的生活還沒有被驚人的事件政治化之前,我只是不斷地一個接一個地為各種程序添加擴展,其中多數和Lisp無關。不過,其間,我寫了一個文本編輯器,叫Emacs。Emacs的有趣之處在于它有一個編程語言,用戶的編輯命令可以用這個解釋性語言編寫,這樣你就可以在編輯時加載新的編輯命令。你可以修改你正在用的編輯程序并且繼續編輯。這樣,我們就有了一個除了編程還可做其他有用之事的系統,而且你在使用時還可以對它進行編程。我不知道Emacs是不是第一個這樣的工具,但是作為編輯器它確實是第一個。

這種構造龐大、復雜的程序作為自己的編輯器,然后再和其他人交換的精神正是我們當時在人工智能實驗室擁有的、驅動自由合作精神的動力。它的思想就是你可以把你擁有的程序的拷貝分發給想要的人。我們和任何想要的人分享,它們是人類的知識。所以盡管我們分享軟件的方式和設計Emacs之間并不存在有組織的政治關聯,我仍然確信它們有聯系,也許是不自覺的聯系。我認為正是我們在人工智能實驗室生活方式的屬性導致了Emacs的誕生并使之發展。

最初的Emacs不帶Lisp。其底層語言、一個非解釋性語言—是PDP-10匯編語言。我們編寫的解釋器實際上不是為Emacs寫的,它是為TECO編寫的。TECO是我們的文本編輯器,也是一個極其丑陋的編程語言,能有多丑陋就有多丑陋。其原因是它本來就不是作為編程語言設計的,它是作為編輯器和命令語言設計的。比如,命令‘5l’意思是‘移動5行’,或者用‘i’加上一個字符串,再加上ESC按鍵來插入該字符串。你可以輸入代表一系列命令的字符串,這叫命令字符串。你可以用ESC ESC做結尾,這樣該串命令就執行了。

不過,人們想要擴展該語言使之帶上編程能力,所以人們就添加了一些功能。例如,最早添加的就有循環結構,就是< >。你把東西放在這兩個符號之間,它們就循環了。還有一些晦澀的命令用來定義退出循環的條件。為了構造Emacs,我們(1)添加了可以創建帶名稱子函數的功能。在此之前,有點像Basic語言,子函數只能有一個字母的名稱。這對編寫大型程序來說有點難,所以我們就添加了長文件名功能。實際上,還有一些相當復雜的功能;我認為Lisp的unwind-protect功能就來自TECO

我們開始添加一些相當復雜的功能,都是用我們所知的那個最丑陋的語法完成的,而它是可行的—人們終究能夠使用它來完成大型程序。這里,明顯的教訓就是使用諸如TECO這樣不是為編程設計的語言是一個錯誤。構建擴展的語言不能是事后再想的編程語言;它應該按照編程語言來設計。事實上,我們發現Lisp是做這件事的最佳語言。

Bernie Greenberg是此事的發現者(2)。他用Multics MacLisp寫了一個Emacs,而且他使用MacLisp編寫命令的方式直截了當。這個編輯器本身完全是用Lisp編寫的。Multics Emacs是一個巨大的成功—編寫新的編輯命令是如此的方便,以至于他辦公室里的秘書們都開始學習怎么用了。他們使用的是一個介紹如何擴展Emacs的手冊,手冊里沒說這就是編程。因此,秘書們并不認為他們在編程,也就沒被嚇跑。他們閱讀手冊,發現自己也可以做不少有用的事,他們學會了編程。

這樣,Bernie看到一個應用程序—為你完成任務的程序—如果內置了Lisp,并且人們可以編寫Lisp程序來擴展該應用程序,那么它實際上就是人們學習編程的一個好方法。這給了人們編寫實用小程序的機會,而這在多數其他場合是不可能的。人們被自己的實用程序鼓勵著—就在最困難的階段—就在他們不相信自己可以編程的時候,直到他們最后成為程序員。

此時,人們開始思考他們要怎樣在一個并沒有全部Lisp支持的平臺上做到這一切。Multics MacLisp既有編譯器,也有解釋器—它是一個完整的Lisp系統—但是人們想要的是在其他沒有Lisp編譯器的系統上實現類似的東西。不過,如果你沒有Lisp編譯器,你無法用Lisp編寫整個編輯器—如果只能運行解釋器的話,它太慢了,尤其是顯示刷新。因此我們開發了一項混合技術。其思想是寫一個Lisp解釋器和編輯器的底層部分,把他們結合在一起,這樣編輯器就內置了Lisp功能。這些就是我們需要優化的部分。這項技術是我們已經在原始的Emacs上有意識地實踐了的技術,因為我們用機器語言重新編寫了某些相當上層的功能,并且把它們作為TECO的基本命令。比如,TECO有一個填充段落的基本命令(實際上,是完成填充段落的大多數工作,因為其中一些不耗時的工作可以在上層由一個TECO程序來完成)。你可以編寫一個TECO程序來完成整個任務,但是它太慢了,所以我們對其部分使用了機器語言做出優化。在此(指混合技術),編輯器的絕大部分是用Lisp編寫的,但是那些需要非常快速運行的部分是用底層語言寫的。

因此,當我編寫第二版Emacs時,我采用了同樣的設計。底層的語言不再是機器語言,而是C。就編寫運行在類Unix系統上的可移植程序來說,C是一個優秀的、高效的語言。雖然有一個Lisp解釋器,但是我直接用C實現了一些特定的編輯功能—管理編輯器的緩存、插入起始文本、讀寫文件、刷新屏幕顯示以及管理編輯窗口。

當時,它不再是第一個用C編寫并運行在Unix上的Emacs了。第一個是由James Gosling完成的,就是GosMacs。他有些奇怪。一開始,他看來還是受到了原始Emacs的合作和分享精神的影響。我首先在MIT向人們發布了Emacs。有人想要把它移植到Twenex系統—它最初只運行在我們在MIT使用的不兼容分時系統上。人們把它移植到了Twenex上,這意味著世界上可能有數百個設備可以安裝該Emacs。我們開始發布該版本,發行遵循的是“你必須發回所有的改進”這樣大家都受益。沒有人會刻意強調這個規則,但是就我所知人們都是合作的。

Gosling一開始,的確看起來是以這樣的精神參與的。他在一個使用手冊里稱此程序為Emacs,希望社區能夠改善之,使之配得上這個名字。這是參與社區的正確方式—請大家參與并使程序更好。但是在此之后,他似乎改變了態度,并把程序賣給了一個公司。

那時,我正在為GNU系統而忙碌(一個類似Unix的自由軟件操作系統,許多人錯誤地稱之為“Linux”)。那時并沒有跑在Unix上的自由軟件版的Emacs編輯器。不過,我有一個參與了Gosling的Emacs開發的朋友。Gosling通過郵件給予他發布自己版本的許可。他建議我使用他的版本。然后,我發現Gosling的Emacs帶的不是真的Lisp。它帶的編程語言是‘mocklisp’,其語法看起來像是Lisp,但是沒有Lisp的數據結構。所以其程序不是數據,而且也缺失Lisp的重要元素。其數據結構是字符串、數字和其他一些專門結構。

我得出我不能使用該程序并且要完全替換該程序的結論,第一步就是編寫一個真正的Lisp解釋器。我逐步用真正的Lisp數據結構替換了該編輯器的每個部分,而不是使用其專門的數據結構,并使編輯器的內部數據結構對用戶的Lisp程序開放,使用戶程序能夠處理編輯器內部數據。

顯示刷新是個例外。很長時間以來,顯示刷新像是一個另類世界。編輯器一旦進入顯示刷新的世界,事情就變成對垃圾數據收集不安全的非常特殊的數據結構,它們對中斷處理也不安全,而且你在此過程中無法運行任何Lisp程序。我們已經修改了這部分—現在你在顯示刷新時也可以運行Lisp代碼。這是一件很便利的事。

這個第二版的Emacs是‘自由軟件’以該詞匯的當今意義來說—它是力爭軟件自由的政治運動的一部分。該運動的精髓就是每個人都應該有自由做我們在MIT的那段歲月做的事,一起開發軟件,只要愿意就可以一起工作。這就是自由軟件的基礎—也是我的經歷,是我在MIT人工智能實驗室的生活—為人類的知識而工作,而不是阻礙其他人使用和傳播人類的知識。

那時,你可以用和造非Lisp專用機差不多的價錢造一臺電腦,它運行Lisp的速度要快得多,而且對每個指令都做類型檢查。普通電腦一般是讓你在運行速度和類型檢查之間選一個。所以,是的,你可能使用Lisp編譯器讓你的程序運行很快,但是如果你對數字做car1時,結果是無效的,最終導致程序崩潰。

該Lisp電腦運行指令的速度幾乎和其他電腦一樣快,但是它對每個指令—car指令都會做數據類型檢查—所以當你在編譯過的程序里試圖用car指令處理數字時,系統會立即報錯。我們制造了這種電腦并且有一個專門的Lisp操作系統。該系統幾乎完全是用Lisp編寫的,只有一部分是用microcode編寫的。人們對大規模造這種機器很感興趣,這意味著他們應該開個公司。

對開什么樣的公司,大家有兩種不同的想法。Greenblatt想開一個他稱之為“黑客”的公司。這意味著該公司會由黑客運作并且以有利于黑客的方式運作。另一個目的是要保持人工智能實驗室的文化(3)。不幸的是,Greenblatt沒有任何商業經驗,所以Lisp電腦團隊的其他人對Greenblatt會不會成功表示懷疑。他們認為他拒絕外部資金的做法行不通。

他為什么要避免外部投資呢?因為如果一個公司引入了外部投資者,他們就會掌控公司并且不會讓你有任何道德上的猶豫。最終,如果你稍有猶豫,他們也會踢開你。

所以,Greenblatt認為他可以找到預先付款的客戶。他們再造電腦發送給該客戶;有了這些利潤之后,他們就可以再造更多的電腦,然后再銷售,然后再造更多的電腦,如此進行下去。組內的其他人覺得這樣不行。

然后,Greenblatt就雇傭了Russell Noftsker,就是招我進來的人,他后來離開了人工智能實驗室并開創了一個成功的公司。Russell被認為很有商業頭腦。他向組內的其他人展示了他的商業才智,他說:“我們拋開Greenblatt,不要管他的想法,我們去開另一間公司。”背后捅刀子,明顯是真正的生意人。這些人決定開一個叫Symbolics的公司。他們吸納外部投資、不會有任何良心不安、竭盡所能獲取成功。

但是Greenblatt并沒有放棄。他和少數忠誠于他的人還是決定開辦了Lisp Machines公司,并按自己的計劃前進。你猜怎么著,他們成功了!他們找到了一個預先付款的客戶。他們制造了電腦并賣了出去,并制造了越來越多的電腦。盡管沒有組內多數人的支持,他們實際上還是成功了。Symbolics也成功地啟動了,所以你有兩家互相競爭的Lisp電腦公司。當Symbolics看到LMI不是走向失敗時,他們開始尋機搞破壞。

因此,實驗室的被離棄接著是實驗室的“戰爭”。離棄是因為Symbolics挖走了實驗室的所有黑客,只剩下我和幾個在LMI兼職的人。然后,他們又援引條例把在MIT兼職的人趕走,因此他們全都走了,只剩下我。人工智能實驗室現在沒什么希望了。而且MIT對這兩個公司做了非常愚蠢的安排。這是一個三方合同,其中兩家公司都被授權使用Lisp電腦系統的源代碼。這兩家公司都需要讓MIT使用他們的更改。但是合同沒有說MIT有權將這些代碼放入由兩家公司授權的MITLisp電腦系統。沒有人預見到實驗室的黑客小組會被徹底毀滅,但是它就是被毀滅了。

于是,Symbolics啟動了一個計劃(4)。他們對實驗室說,“我們會持續讓你們使用我們的系統改進,但是你們不能把這些改進裝到MIT的Lisp電腦系統上。不過,我們會讓你們使用Symbolics的Lisp電腦系統,你們可以在這些系統上運行改進版,但是僅此而已。”

這實際上是要求我們只能選擇一邊,要么使用MIT的系統版本,要么使用Symbolics的版本。我們選擇哪一邊,就決定了我們的系統改進會進入到哪一邊。如果我們為改進Symbolics的版本而工作,我們就只是在幫助Symbolics。如果我們使用和改進MIT的系統版本,兩個公司都能夠得到我們的工作,但是Symbolics認為這是在支持LMI,因為這會幫助LMI生存下去。因此,我們不被允許再保持中立。

直到此時,我都沒有站在其中任何一個公司的一邊,雖然我看到社區和軟件發生的一切感到非常難受。但是現在,Symbolics強迫我做出選擇。所以,為了使Lisp Machines公司能夠繼續(5)—我開始復制Symbolics對Lisp電腦系統所作的全部改進。我把這些改進用自己的想法同樣實現出來(就是說,代碼是我自己寫的)。

過了一陣,(6),我得出結論,不看他們的代碼可能更好。當他們宣布beta版時,通過看發布聲明,我知道了有什么功能,然后自己實現它們。當他們發行正式版時,我也實現了這些功能。

如此這樣,有兩年的時間,我阻止他們把Lisp Machines公司消滅;這兩個公司同時存在。但是,我不想這樣年復一年地懲罰一個人,僅僅只是阻撓一樁罪惡。我覺得他們已經受到了徹底的懲罰,因為他們陷入了無法擺脫的競爭漩渦之中(7)。與此同時,是時候再開始創建一個新的社區來代替那個被他們以及其他人毀滅的社區了。

70年代的Lisp社區不限于MIT人工智能實驗室,并不是所有的黑客都在MIT。Symbolics發起的戰爭毀滅了MIT社區,但是同時還有其他事件在進行。有人放棄了合作,這些也毀滅著社區,社區所剩寥寥了。

一旦我不再懲罰Symbolics,我就不得不考慮下一步做什么。我必須做一個自由的操作系統,這很明顯—人們能夠一起工作和分享的方法就是有一個自由的操作系統。

一開始,我想要做一個基于Lisp的系統,但是我認識到那在技術上并不一個好主意。要做像Lisp電腦那樣的系統,你需要專用的微代碼。這種微代碼使你能夠和其他電腦一樣快速地執行程序,同時還能獲益于類型檢查。沒有微代碼,你就只相當于其他機器上的Lisp編譯器。程序可以更快,但是并不安全。如果你在一個分時系統上運行一個這樣的程序還湊合—一個程序崩潰并不是災難,用戶程序時不時地都可能會崩潰。但是這樣編寫操作系統就不行,所以我拋棄了做類似Lisp電腦系統的想法。

我決定做一個類似Unix的操作系統,可能會帶一個能夠運行用戶程序的Lisp環境。內核不必是用Lisp編寫的,但是我們應當有Lisp。所以正是這個操作系統、GNU操作系統的開發指引我編寫了GNU Emacs。在編寫的過程中,我的目的是做一個盡可能最小的Lisp系統。該程序的大小是非常重要的考量。

在1985年,有些人電腦的內存是不帶虛擬內存的1兆字節。他們也想要運行GNU Emacs。這意味著我必須使該程序盡可能地小。

舉個例子,當時的循環結構只有‘while’,它簡單到極致。你無法直接跳出‘while’循環,你只能進行一次異常捕獲(catch)和一次異常拋出(throw),或者判斷控制循環的變量。這個例子說明我為了使程序變小,做出了什么樣的努力。我們也沒有‘caar’和‘cadr’等等指令;“盡可能減少不必要的東西”是GNU Emacs的精髓,是Emacs Lisp的精髓,從一開始就是這樣。

當然,現在的電腦大了,我們也不再追求那樣的極致。我們加入了‘caar’和‘cadr’等指令,而且我們最近也會添加另外的循環結構。現在我們愿意擴展它,但是我們不想把它擴展成common Lisp那樣。我曾在Lisp電腦上實現過Common Lisp,我對之并不是十分滿意。其中我非常不喜歡的就是關鍵字參數(8)。在我看來,它們不算Lispy;雖然我有時也用關鍵字,但是我把我用的次數控制到最小。

這并不是GNU工程涉及Lisp的結束。后來在1995年左右,我們計劃啟動一個圖形化桌面項目。我們很清楚該桌面程序的主要編程語言應該能夠便利地擴展該桌面程序,就像我們的編輯器一樣。問題在于這應該是一個什么語言。

此時,TCL作為候選語言的呼聲很高。我非常看不上TCL,基本上因為它不是Lisp語言。它稍稍有點像Lisp,但是其語義上不是,而且也不簡潔。然后,有人給我看了一個廣告,其中說Sun公司正試圖雇人把TCL變成全世界“擴展語言的實質標準”。我在想,“我們必須阻止這件事”,所以我們開始讓Scheme成為GNU的標準擴展語言。不是Common Lisp,因為它太龐大了。其思想是,我們把Scheme解釋器連接到應用程序中,就像TCL那樣。然后,我們就可以建議這是所有GNU程序首選的擴展包。

使用這個強大的Lisp分支語言作為基本擴展語言會給你帶來一個有趣的好處。你將能夠把其他語言翻譯成基本擴展語言來實現其他語言。如果你的基本語言是TCL,那么你就不能夠輕易地用翻譯成TCL來實現Lisp。但是如果你的基本語言是Lisp,那么翻譯就不是難事。我們的想法是,如果每個擴展應用都支持Scheme,那么你可以用Scheme實現TCL或Python或Perl,用來把應用翻譯成Scheme。之后,你就可以把它加載到每個應用,然后就可以用自己最喜愛的語言來定制應用了,其他定制也類似。

如果擴展語言很弱,用戶就不得不使用你提供的唯一語言。這就意味著,喜歡特定語言的人們將不得不和開發者選擇的語言競爭—他們會說“應用開發者,請把我的語言添加到你的應用中,而不是添加別人的。”這樣,用戶就根本沒有選擇的余地—他們只能接受應用帶來的語言,并受制于[該語言]。但是如果你有一個強大的語言,它能夠實現其他語言,那么你就給了用戶自由選擇語言的權利,我們就不再有語言選擇的戰爭了。這正是我們所希望的‘Guile’,我們的scheme解釋器,能夠做到這一切。去年夏天,我們有人完成了從Python到Scheme的翻譯器。我不太確定這個是否已經全部完成,不過如果有人對這個項目感興趣,請聯系我們。這就是我們未來的計劃。

我一直沒有提自由軟件,不過現在讓我簡單說一下它的意義。自由軟件指的不是價格;它的意思不是你可以免費得到的軟件。(它可以是你付費得到的軟件,也可以是你免費獲得的拷貝。)它的意思是作為用戶,你有一些自由。其中的關鍵是你有自由運行該軟件、你有自由研究其所作所為、你有自由按照自己的需求修改該軟件、你有自由向其他人發布該軟件以及發布修改后的軟件。這就是自由軟件的定義。如果你使用的是非自由軟件,你就失去了這些關鍵的自由,所以請不要使用非自由軟件。

GNU工程的目的就是提供代替非自由軟件的自由軟件,讓人們能夠更容易地拒絕非自由軟件對自由的侵害、對用戶的控制。對那些缺少道德勇氣來拒絕非自由軟件的人來說,如果你需要的是實用性,那么我們將盡力提供一個自由的替代使你能夠在較少混亂、較少犧牲實用性的情況下,轉移到自由軟件。你失去的實用性當然是越少越好。我們希望你能夠更容易地獲得自由、并且能夠合作互助。

合作互助關乎自由。人們習慣于認為自由和社會合作是對立的。但是,此時我們在同一條戰壕內。使用自由軟件,你就有自由和其他人合作,并且也有自由幫助你自己。使用非自由軟件,你就被控制,人們被分化。你無權和其他人分享,你沒有自由去合作互助或幫助社會,正如你沒有自由來幫助你自己。使用非自由軟件的用戶就是這樣孤立和無助。

我們已經開發了范圍龐大的自由軟件。我們完成了人們曾經說永遠完不成的事;我們有兩個自由軟件操作系統。我們有很多應用,但我們顯然還有更多的要做。所以,我們需要你們的幫助。我請求你們成為GNU工程的志愿者;幫助我們開發能執行更多任務的自由軟件。請參看http://www.poucj.com.cn/help來了解怎么幫助我們。如果你想訂購一些東西,我們的主頁上有一個鏈接。如果你想了解我們的哲學,請閱讀/philosophy。如果你在找可用的自由軟件,請到/directory,現在大約有1900個軟件包(這只是所有自由軟件的一部分)。請編寫更多的自由軟件并貢獻給我們。我的文集,“自由軟件和自由社會”,正在發售,你可以在www.poucj.com.cn購買。祝你們開發愉快!

  1. Guy Steele設計了Emacs最初的對稱命令集合;然后我們開始構造Emacs(在TECO的基礎上),但是在一段長期的聯合開發之后,Steele漸漸離開了,所以我獨自完成了Emacs。其他人,特別是Eugene C. Cicciarelli和Mike McMahon后來也做出了顯著的貢獻。
  2. Bernie Greenberg說Dan Weinreb在Lisp電腦上的Emacs要早于Greenberg在Multics的版本。我在此對我的錯誤道歉。
  3. Greenblatt的計劃,就我的理解,是請實驗室的人員兼職,這樣他們還能夠繼續在人工智能實驗室的本職工作。Symbolics采取的是全職雇傭,所以實驗室的人員就不能在MIT工作了。
  4. 該計劃的背景,我在演講里沒有明說,是在開始階段,人工智能實驗室的黑客們,不管是在Symbolics,還是在LMI,都繼續把他們的改進貢獻給MIT的Lisp電腦系統—盡管合同并沒有要求這樣做。Symbolics的計劃卻是單方面割裂合作。
  5. 這并不是說我特別關注LMI的命運,我只是不想讓Symbolics通過攻擊人工智能實驗室獲益。
  6. 這個陳述常被曲解為我從來沒有看過Symbolics的代碼。實際上,它說的是我一開始看了Symbolics的代碼。這些代碼就在MIT,我有權看的,而且最初我就是這樣了解到他們做了改動。

    不過,這意味著我不得不花力氣找到其他的解決方法,這樣才能避免復制Symbolics的代碼。一段時間之后,我覺得不看這些代碼更好。這樣的話,我就可以按最好的方法來實現代碼,而不用考慮是否用了Symbolics的代碼。

  7. Symbolics曾經向MIT抗議:我的工作阻撓了他們的計劃而使Symbolics損失一百萬美元。
  8. 我并不介意非常復雜和重量級的函數使用關鍵字參數。我討厭的是連諸如“member”這樣的簡單函數也要使用關鍵字參數。

譯注

  1. car:是Lisp語言的一個基本指令。
最頂

[FSF 標志]“自由軟件基金會(FSF)是一個非盈利組織。我們的使命是在全球范圍內促進計算機用戶的自由。我們捍衛所有軟件用戶的權利。”

加入 購物

上海基诺彩票中奖号码 快乐十分天津走势图 网站赌博快速赛车 股票分析师工资高吗 学生如何微信赚钱方法 企业管理主要管理什么 江西快3代理 168直播现场开奖结果查询 中巨奖的征兆 飞鱼彩票玩法规则 真钱捕鱼平台 时时彩后二码稳赚 怎样才能打好麻将 比特币现金交易排行榜 时时彩三星走势图彩经网 江苏快3推荐 三爱富股票行情