转:有关Forth语言
轉自:http://blog.codingnow.com/2010/06/masterminds_of_programming_forth.html
把其中比較有意思的幾段話摘出來:
只要我聽到有人吹噓代碼達到了上百萬行,我就知道他們肯定前面理解錯問題了。當代沒啥問題需要寫幾百萬行代碼。要么是程序員太粗心、要么項目經理太混蛋、要么就是為兼容一些不存在的需求。
---
哦,我在六十年代去了趟 Stanford ,那里有組研究生正在寫一個 ALGOL 編譯器——Burroughs 5500 用的版本。當時我想他們不過才三四個人,就三四個人坐在那寫一個編譯器,我那個內牛滿面啊。
---
操作系統是另一個稀奇古怪的東西。操作系統嚇人的復雜,而且完全沒用。它是 Bill Gates 成功向世界推銷出去的一個光彩奪目的概念。這可能是世界上出現的最大的騙局。
操作系統對你來說做著絕對的無用功。其實你有這樣一些東西就夠了:一個叫作磁盤驅動程序的子程序,一個叫什么什么通訊支持的子程序,而在現代社會,操作系統啥也沒做。實際上,Windows 花了大量時間在包裝層上,或是諸如磁盤管理器這樣不相干的東西上。你有了上 G 的磁盤,有了上 M 的內存。世界格局發生了變化,使得操作系統不那么有用了。
后面是轉載的內容。
今天晚上繼續讀 《Masterminds of Programming》,忍不住又翻譯了半章關于 Forth 之父的訪談。我以前讀過幾篇更早時期關于他的訪談,部分了解他的觀點。小時候還特別迷 Forth 。這位神叨叨的老頭很有意思。
沒看過原來的譯本,只是自己按自己的理解翻了第 4 章 Forth 的前一半。我也算對 Forth 很有愛的人吧,也還了解 Forth 里諸如 ITC (Indirected-threaded code) 這種術語到底指的什么,不過還是覺得翻譯有點吃力。
對 Forth 同樣有愛的同學們姑且看之吧。
Forth 語言及語言的設計
你怎樣定義 Forth
Chunk: Forth 是一門計算機編程語言,其語法規模簡到極致。把參數棧專門獨立出來是語言的一大特色,這使得子程序調用非常高效。因此,語言采用后綴表達式(先列參數,再跟操作符),并鼓勵把程序高度細分成眾多短小的子程序的風格。這些子程序共享棧上參數。
我曾經讀過關于 Forth 這個名字的介紹,據說是象征著第四代軟件開發。你可以給我們多介紹一些嗎?
Chunk: Forth 源于 "Fourth (第四)" 這個詞。暗指 “第四代計算機語言”。據我回憶,我跳過了一代。FORTRAN/COBOL 是第一代;Algol/Lisp 是第二代。這些語言都強調語法。語法越詳盡,越能檢查出錯誤。但大部分錯誤是語法錯誤。我決定將語法元素減到最小,而強調其語義。被加載的 Forth 詞就真正的表達其含義。
你把 Forth 當成一個語言工具集。我這樣理解這個視角:給出相對其它語言更簡單的語法,提供比其它語言所用的更短的詞構成一個詞匯表的能力。我還漏掉了什么嗎?
Chunk Moore: 就是這樣。其中關鍵一點是,我們盡其可能的分解。一段 Forth 程序有大量的小詞構成。相對來看,同樣的 C 程序用到的詞則少的多,而且每個詞都要大的多。
我所謂短小的詞,是指可以用一行源代碼定義出來的詞。你可以用剛定義出來的詞來定義下一個新詞,如此層疊,最終得到數千個詞的定義,最終形成了語言。這里面臨的挑戰是:1) 判斷哪些詞是有用的。2) 記住所有定義出來的詞。我現在正在編寫的應用程序有上千個詞。所以我寫了個工具來搜索這些詞,不過你必須先記得有這個詞,大概怎么拼才找得出來。
好了,現在有了種完全不同的編程風格,程序員需要一點時間才能適應。我已經看過太多 Forth 程序就像是從 C 程序直譯過來的。這樣做可不對。正確的做法是從零開始。關于這個工具集還有一個有趣的地方,只要你好好做,定義出來的新詞和內核中預定義的詞并無不同。它們一樣高效,對外的意義也相同。定義你自己詞是沒有額外開銷的。
外部結構看起來是由許多小詞組成,這一點是源于 Forth 的實現嗎?
Chunk: 這是我們非常高效的子程序調用序列的結果。這里面沒有參數傳遞,因為語言是基于棧的。所有的一切僅僅只是調用和返回。而棧暴露在外。讓機器識別的語言編譯在一起,進入和退出字程序只需要逐字翻譯成一條 call 指令和一條 return 指令。你總可以進一步的達到匯編語言層面,得到等價的指令。你可以定義一個詞剛好執行一條真正的機器指令,而不是做一次子程序調用,這樣,它可以匹敵任何其它語言的效率,甚至比一些語言更高效。
這樣就沒有 C 調用的消耗
Chunk: 沒錯。這賦予了程序員巨大的靈活性。如果你能聰明的分解問題,你不僅僅只是高效的完整任務,還使得完成的過程變得格外易讀。
另一方面,如果你做的很糟糕,你最終的代碼世界上只有你一個人能解讀——連你那全知全曉的經理都看不懂你寫的代碼。你可以寫出天書。所以,這是把雙刃劍。你能做的完美無暇,也能弄得污七八糟。
你能說點什么(或展示點代碼)讓用別的編程語言的開發人員對 Forth 一見鐘情嗎?
Chunk: 讓有經驗的程序員對 Forth 感興趣挺難的。這是因為他已經為他正在使用的語言/操作系統相關的工具學習做了大量的投資。為他的應用程序積累了許多。即使是告訴他們,Forth 會更小,更塊,更簡單,也及不上把所有東西都重寫的代價。一個新手程序員,或是一個沒這么干擾的需要寫點代碼的工程師可能更容易接受一點。嗯,或是有某個有經驗的程序員要開個新項目,而這個項目有些新的約束條件,比如我現在在做的多核芯片上做開發。
你提到你見過的大量 Forth 程序看起來像 C 程序。那么你自己怎么設計一個更好的 Forth 程序的?
Chunk: 由底至上。
首先,你估計會有一些 I/O 信號要去產生,好吧,就來產生它們。這樣你就寫一些代碼控制這些信號的產生過程。然后你一點點來,知道最終構建出高層的詞。假定你把它起了個名字叫 go ,接下來你敲一下 go ,一切如期發生。
我不信任由頂向下的系統分析方法。他們判斷問題是什么,然后再分解,分解出來卻很難實現。
領域驅動設計建議以客戶的詞匯來描述商務邏輯。在創建詞庫和使用你問題域的術語之間有什么聯系?
Chunk: 最好是程序員在開始寫代碼前了解那個領域。我會和客戶溝通。我會傾聽他用的詞匯,并試著用這些詞,這樣他也能明白程序在做什么。Forth 因其采用后綴記號法使代碼費用易讀。
如果我寫一個經濟有關的應用程序,我可能會用一個叫作 "percent" 詞。你可以在代碼中寫 "2.03 percent" 。這里 percent 的參數就是 2.03 ,一切都和看起來那樣自然。
一個從穿孔卡片計算機時代開始的項目居然到了互聯網時代的現代計算機上還這么有用。Forth 于 1968 年在 IBM 1130 上設計并運用。它到了 2007 年繼續為并行處理所用,這真奇妙。
Chunk: 其間 Forth 也進化了。不過 Forth 可能是最為簡潔的計算機語言。它沒給程序員附加任何約束。他(她)可以瘦的層次化方式定義一些詞精確切合問題的原貌。
你在設計程序時,是否把讓程序讀起來像英文一樣做為一個目標?
Chunk: 在非常高的層次上看,是這樣。但英文并非功能性描述的好語言。英語不是設計來干這個的,不過英語和 Forth 有個共同的特性,就是你能定義新詞。
你用以前定義好的許多詞通過解釋的方式來定義新的詞匯。對于自然語言來說,有可能不嚴謹。如果你查字典的話,會發現有些是循環定義,你查不到本質內容。
是不是把注意力轉移到一堆詞上面,比 C 里出現的那些各種括號來說,Forth 因此能寫出更好味道的程序?
Chunk: 希望如此。這使得 Forth 程序員去關注事物的外貌,而不僅僅是其功能。如果你能組織起一系列的詞,把它們有序的排列起來,會感覺很好。這正是為什么我開發了 colorForth 。我曾為 Forth 里老的語法煩惱。比如,按現在的方法,你要做注釋,就必須用一左括號和一右括號來括起來表示。
我看著所有標點符號說,“好吧,可能還有更好的方式。” 這更好的方式最麻煩的一點是,源代碼中每一個詞都需要附加一個標簽。如果我能忍受這點開銷,所有的符號都另人舒服的消失了,取而代之的是,每個詞都有了顏色。對我來說,這是個優雅的表達其功能的方式。
我遭到了色盲群體的抨擊。他們對我試圖把他們排出程序員行列的做法義憤填膺。不過某人最后想了個招,用字體的區分代替顏色的區分,這也是個不錯的方法。
關鍵點在于,每個詞有個四位的標簽,這能區分出 16 種事物。編譯器可以立刻感知它要做什么,而不用從上下文去推斷。
第二代和第三代語言都皈依了極簡主義,舉例來說就是實現了 meta-circular bootstrapping (圓環自舉,靠自身把自身運作起來)。Forth 是在對語言的概念定義以及硬件需求量方面的極簡主義的最好的例子。這是當年的時代特征或是你做出的跨時代的創舉嗎?
Chunk: 非也。當時再三考慮的設計目標是盡可能的做一個最小的內核。只預定義最為必要的幾個詞,然后讓程序員再去添加他覺得合適的。主要因素是可移植性。在那個時代,大打的小型計算機,接著又是一大坨微型計算機。而我必須把 Forth 弄到如此之多的機器上去。
我想干這點事能盡量輕松點。我要干的就是弄出一個百來個詞的內核,以此能夠組成一個,我叫作操作系統,但其實不完全是操作系統的東西,這個東西再給出幾百個詞為人所用。接下來你就能在這上面做開發了。
我來提供做前兩個階段的工作,讓程序員去做第三個。我也經常做應用程序開發程序員。定義我知道的詞總是很有必要。頭一百個詞可能用機器語言或匯編語言定義,至少是直接和特定平臺打交道。第二和第三百個詞可以是高層次的詞,在較低層次最小化機器依賴性。接下來,應用程序就能最大限度的做到機器無關了,這樣很容易把程序從一臺機器移植到另一臺上。
當初你能在第二階段之上方便的移植嗎?
Chunk: 絕對如此。比如我有個文本編輯器,用來編輯源代碼的。它總是在各種機器上不需要修改任何地方都能用。
坊間流傳著一個傳說,每次你看到一臺新機器,你就立刻動手把 Forth 移植到上面。是說的這個嗎?
Chunk: 沒錯。實際上對于理解一臺機器如何工作;了解那些可以用來更容易實現 Forth 標準包里詞的詭異機器特性;這是條最簡單的途徑。
你是怎樣發明 indirect-threaded code 的?
Chunk: 代碼是一個很微妙的概念。每個 Forth 詞在字典里有一個入口。對于基于直接線索的編碼(direct-threaded code ,有譯為直接串線編碼),遇到引用每個詞的位置直接指向要執行的代碼。而基于間接線索的編碼(indirect-threaded code 有譯為間接串線編碼) 則指明一個包含了代碼所在地址的位置。這使得地址之外的信息能被訪問到——比如,一個變量的值。
這可能是最為緊湊的詞組織方法了。它可以等價于基于直接線索的編碼和基于子程序的編碼(subroutine-threaded code ,即類似 C 語言編譯成的那種直接調用子程序方式)。當然這個概念和術語在 1970 年時還沒有。但對我來說,這是實現各種各樣詞的最自然方式。
Forth 會如何影響計算機系統的未來走向嗎?
Chunk: 這已經在發生了。我在微處理器優化方面干了 25 年,最新近的一個多核芯片的核心是 Forth 計算機。
Forth 提供了些啥?作為一個簡單的語言,它使得這樣一臺簡單的計算機:有 256 個字的本地內存;兩個下壓棧;32 條指令;異步操作;易于和相鄰機器通訊;可以很小,且功耗極低。
Forth 鼓勵被高度分解的程序。這非常適合在多核芯片上做并行處理。大量小程序鼓勵你每一個都深思熟慮的設計。這樣最終你可能只需要寫 1% 的代碼就夠了。
只要我聽到有人吹噓代碼達到了上百萬行,我就知道他們肯定前面理解錯問題了。當代沒啥問題需要寫幾百萬行代碼。要么是程序員太粗心、要么項目經理太混蛋、要么就是為兼容一些不存在的需求。
使用 Forth 對需要小計算機編程是個巨牛叉的策略。別的語言都提供不了相當的模塊化能力和擴展性。尤其計算機越來越小,它們之間必須做網絡化協作(智能微塵?),這就是未來的環境。
這聽起來像 Unix 的重要原則之一:以許多程序,每個只做一件事,相互作用。這依舊是當今最好的設計嗎?在一臺機器上跑多個程序會被通過網絡運行的多個程序取代嗎?
Chunk: 讓代碼跑在多個線程上的這個概念,被 Unix 和別的操作系統所實現。這是并行化處理的先驅。但這里有些重要的差別。
大的計算機承擔得起多線程通常會要付出的一些代價。最終弄出個龐大的操作系統。對于并行化處理來說,永遠都是計算機越多越好。
在資源一定的情況下,更多的計算機意味著更小的計算機。但很小的計算機是承擔不起在大計算機上承擔的代價的。
小的計算機的網絡化會發生在芯片之上,通過 RF 連接的芯片之間。小的計算機內存也小。操作系統無處容身。計算機必須自治,自己要有能力保持通訊。因此通訊環節必須簡單——沒有那些煞費苦心的協議。軟件也必須緊湊高效。最為理想的應用程序就是 Forth 了。
那些需要數百萬行代碼筑就的系統將會淡出歷史舞臺,是它們造就了巨大的中央計算機。分布式技術需要條不同的思路。
一門語言若是設計成支持繁雜的,拘泥于語法條條框框的代碼,就會鼓勵程序員寫出巨大的程序。并以此自得,洋洋得意。沒什么壓力去尋找緊湊的方案。
以繁雜句法定義出來的語言生成的代碼也可以很小,但通常做不到。以語法默示的實現流程導致了笨拙而不那么高效的目標代碼。這對于小的計算機來說并不合適。一門良好設計的語言在源碼和目標碼之間存在一對一的聯系。這向程序員昭顯了源碼如何生成為最終代碼。注重性能、減少對文檔的需求,使得程序員感到滿足。
Forth 設計成對于源代碼和二進制輸入的目標代碼皆很緊湊,這也是嵌入式開發中廣泛使用的原因。不過在許多其它領域程序員總有別的理由去用別的語言。是不是說這些語言的設計的某些方面只是增加了原代碼或是目標碼的開支嗎?
Chunk: Forth 的確很緊湊。一個因素在于他的語法量很小。
其它語言看起來是故意的增加一些語法,弄出點冗余,可以幫助語法檢查以及錯誤檢測。
Forth 沒提供啥機會用來做錯誤檢查,因為它沒有冗余信息。這也使得源代碼非常緊湊。
我感覺其它語言幾乎所有的錯誤都出在語法上。設計者看起來為程序員犯下編譯器就都能找出來的錯誤創造了條件。這沒啥經濟價值。這不是為寫出正確的代碼自找麻煩嗎。
比如說類型檢查吧。不同的數字類型之間的賦值錯誤會被偵測到。無意中帶來的后果是程序員必須自己來轉換類型,有時就是想回避類型檢查而得到他們真正想干的事情。
語法導致的另一結果是它必須適應所有的應用程序的意圖。這就會越來越復雜。Forth 是一個可擴展的語言。程序員可以創建一些別的語言只能通過編譯器的改進才能獲得同樣性能的結構。而所有的能力不需要一開始就想好提供出來。
Forth 的特征之一是使用后綴操作符。這能簡化編譯器,從源代碼到目標代碼給出一對一的關系。程序員對他寫的代碼的充分理解能增加代碼編譯后的緊湊程度。
**許多最近的計算機語言(尤其是 Python 和 Ruby)都把可讀性引為其關鍵好處。Forth 在這方面與之相較可以從中學到并保持些什么?Forth 能在可讀性方面的定義方面傳授給其它語言些什么東西?
Chunk: 計算機語言都宣稱要可讀。但他們并不可讀。或許對懂這門語言的人來說是可讀的。但初學者還是稀里糊涂的。
問題就在于晦澀、武斷、隱秘的語法中。那些小括號啦,& 符啦,等等。你試著學習它們為啥出現在那里,最終推斷,其實沒什么好理由。但是你還是要按規則辦事。
你無法說這門語言。你必須像 Victor Borgia 那樣嘰里呱啦的把符號都念出來。
Forth 通過最小化語法來減輕這個問題。它用的哪些個神秘符號,@ 和 ! 可以讀成“取”和“存”。這些個使用符號是因為出現的太頻繁了。
程序員被鼓勵使用自然語言中的詞匯。它們不通過標點的間隔組織在一起。若是你選好了詞,你就能構造出有意義的句子。實際上有人用 Forth 來寫詩。
另一個優勢是后綴表示。一個像 “6 英寸”這樣的短語能把操作符“英寸”作用于參數 6,這是非常自然的表達方法。非常的可讀。
另一方面,程序員的任務就是開發吃一組詞來描述問題。這個詞典會變得非常大。讀者需要了解整個詞典使得程序可讀。程序員就必須好好的定義詞。
總而言之,用任何語言,這些都會影響程序的閱讀。
你如何定義你的工作中如何定義成功?
Chunk: 一個優雅的解決方案。
人們并沒有用 Forth 編程。Forth 就是一個程序。他們添加新的詞創建一個詞典來定義問題。當正確的詞被定義出來,一切都渾然天成。接下來你就能你可以互動地解決所有相關問題的任何方面。
舉個例子:我可以定義一些詞來描述一個電路。我以后想把這個電路加到一塊芯片里去,顯示電路的布局,校驗設置規則,模擬跑一下。用來干這些事情的詞決定了應用程序的形態。如果精心選擇這些詞,提供一個緊湊而有效的工具集,然后我就搞定了。
你在哪學會寫編譯器的?在那個年代每個人都必須去寫編譯器嗎?
Chunk: 哦,我在六十年代去了趟 Stanford ,那里有組研究生正在寫一個 ALGOL 編譯器——Burroughs 5500 用的版本。當時我想他們不過才三四個人,就三四個人坐在那寫一個編譯器,我那個內牛滿面啊。
我想,“靠,他們要能做,我也能做。”然后我就干了。其實一點也不難。當年寫編譯器還是有點神秘西西的。
現在其實也還是神秘西西的
Chunk: 嗯,不過已經沒那么神秘了。你看現在新語言一個個的冒出來,我不知道算解釋型的還是編譯型的,不管怎樣,有黑客風范的人都想做一個。
操作系統是另一個稀奇古怪的東西。操作系統嚇人的復雜,而且完全沒用。它是 Bill Gates 成功向世界推銷出去的一個光彩奪目的概念。這可能是世界上出現的最大的騙局。
操作系統對你來說做著絕對的無用功。其實你有這樣一些東西就夠了:一個叫作磁盤驅動程序的子程序,一個叫什么什么通訊支持的子程序,而在現代社會,操作系統啥也沒做。實際上,Windows 花了大量時間在包裝層上,或是諸如磁盤管理器這樣不相干的東西上。你有了上 G 的磁盤,有了上 M 的內存。世界格局發生了變化,使得操作系統不那么有用了。
那設備支持怎么辦?
Chunk: 你對每個設備有一個子程序。那是一個庫,而不是操作系統。你需要那個就裝載哪個。
在工作間隙后,你怎么繼續編程?
Chunk: 在被困擾的時候,我不會中斷我的編碼。我會充滿熱情的思考問題,做夢都會想著它們。我想這是一個 Forth 的特質:在小段時間(以天計)內全神貫注的解決一個問題。這幫助 Forth 應用程序自然的被分解為一個個子項目。幾乎所有的 Forth 代碼都簡單易讀。當我真的要做一些偏激的事情,我會做好注釋。好的注釋能幫我以后回到問題中,不過重新閱讀和理解代碼總還是有必要的。
你在設計或編程中犯過最大的錯誤是什么?你從中學到點什么?
Chunk: 20 多年前,我想為設計 VLSI 芯片開發個工具。我的新電腦上沒有 Forth ,因此我就想用另種方案,寫機器語言。不是匯編,就是用 16 進制碼敲機器指令。
我像我寫 Forth 程序那樣編寫代碼,分層次的定義出需要簡單的相互有關的詞。最終搞定了。我用了這個東西 10 年。但是無法維護,也沒有文檔。最終,我用 Forth 重寫了一遍,這個玩意變得更為小巧而且簡單多了。
我的結論是,Forth 比機器語言更高效。一部分源于其交互性,另一部分是因為它的語法。Forth 的一個很漂亮的方面是,數字可以用計算它們的表達式文檔化的表達。
總結
以上是生活随笔為你收集整理的转:有关Forth语言的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vs下活动解决方案管理器中x86 x64
- 下一篇: 第一章 基本架设服务器流程