1x Forth
1x Forth
Charles Moore, April 13, 1999
這篇文章是 Jeff Fox 根據(jù) Charles Moore 談話錄音所寫。
我請(qǐng)求 Chuck Moore 允許我對(duì)這次關(guān)于 15 年來(lái) Forth 語(yǔ)言變遷的談話進(jìn)行錄像。我們安裝了攝像機(jī),他談?wù)摿宋以谶@個(gè)網(wǎng)站上提出的問(wèn)題,但是這一次我們不再把焦點(diǎn)集中在固體物理、 VLSI 或者芯片和調(diào)試方面的經(jīng)驗(yàn),而是 Forth 語(yǔ)言。我覺(jué)得他談?wù)摿诉@些年來(lái)的 Forth 語(yǔ)言,但是相比我所關(guān)心的、 30 年前發(fā)明的語(yǔ)言來(lái)說(shuō),他談及了更多的方面。
我介紹 Chuck.
(Jeff Fox) 今天,我請(qǐng) Chuck Moore 對(duì) Forth 做一個(gè)介紹,我想請(qǐng)他談一談對(duì)于自己發(fā)明的語(yǔ)言在最近 15 年里的經(jīng)驗(yàn)。現(xiàn)在我們請(qǐng) Charles Moore 。
(Charles Moore) 這可是一個(gè)大話題,我們談多長(zhǎng)時(shí)間?
(Jeff) 磁帶只有一個(gè)小時(shí)。
(Chuck) 15 年,那差不多是我用計(jì)算機(jī)面對(duì)軟件的整個(gè)經(jīng)歷。回想 15 年前,把重點(diǎn)從 Forth 語(yǔ)言轉(zhuǎn)向 Forth 微處理器的動(dòng)機(jī)主要有兩個(gè)。
首先是軟件的問(wèn)題已經(jīng)解決了。編寫應(yīng)用程序很容易,不用費(fèi)太大的勁。所有的問(wèn)題都是硬件,硬件笨拙、零亂、可靠性差,特別是你需要為客戶的硬件而編寫客戶化的軟件時(shí)。如果你想調(diào)試硬件那就更是一個(gè)大麻煩。這些都說(shuō)明硬件工程師并沒(méi)有做出出色的工作,當(dāng)然,他們比工業(yè)界的軟件工程師做得好,但是沒(méi)有 Forth 軟件工程師做得好。因此我想看看我能夠在這些硬件問(wèn)題方面做些什么。這可能是個(gè)錯(cuò)誤。 Forth 有許多有趣的事情可做,硬件可就不這么有趣了。
我不知道你是不是聽(tīng)過(guò)這些歷史,第一個(gè) Forth 處理器是 Novix ,它也可能是所有這類處理器中的第一個(gè)。它是一個(gè) 16 位的處理器,使用高速工藝制造,平均 8MIPS 。這個(gè)工作很有趣,我們給它配了一個(gè)很好的 Forth 系統(tǒng),稱為 cmForth ,比我為 Forth Inc. 所做的其它 Forth 都更小、更簡(jiǎn)單,后來(lái) ShBoom 是 32 位處理器, 50MIPS 。現(xiàn)在 i21 是最新的成果,它是 20 位的,我很高興地宣布它的速度是: 500MIPS.
每個(gè)處理器都有它自己的 Forth 語(yǔ)言,目標(biāo)非常簡(jiǎn)單:使硬件與軟件結(jié)合的復(fù)雜性最小。只要我沒(méi)有看到其它的人在做這件事情,只是嘴上說(shuō)說(shuō)的人不算,沒(méi)有人真的在使復(fù)雜性最小方面做任何事情,那就是我需要盡力去做的。
我們正在建立一種文化,它不能夠抗拒比如 Y2K 這樣很小的災(zāi)難。一但我們失去了十億美元的封裝廠、一但我們失去了由數(shù)千人組成的程序員團(tuán)隊(duì),我們還能夠重新建立起來(lái)嗎?不用關(guān)心能不能重建的事情?計(jì)算機(jī)值得我們的社會(huì)這樣投入嗎?它本來(lái)可以簡(jiǎn)單得多。如果它更簡(jiǎn)單,那么我對(duì)技術(shù)在未來(lái)不確定社會(huì)中更持久這樣的事情就會(huì)更有信心。
把事情弄復(fù)雜好象是一個(gè)傾向。人們喜歡把它們弄得復(fù)雜,這種情況隨處可見(jiàn)。你可以在電視節(jié)目中是看到,可以在市場(chǎng)的產(chǎn)品中看到,也可以在網(wǎng)站網(wǎng)頁(yè)上看到,簡(jiǎn)單地表示信息不足,你把它弄得精彩。我想可能有一個(gè)最佳的復(fù)雜度是人腦能夠設(shè)計(jì)它們。你把事情弄簡(jiǎn)單了,大眾會(huì)覺(jué)得無(wú)聊,但是你把它們弄得太復(fù)雜,一樣會(huì)失去大眾。
我從來(lái)沒(méi)有因?yàn)楹?jiǎn)單而覺(jué)得無(wú)聊。給我做一件事情更簡(jiǎn)單的方法,我就會(huì)迫不急待地去得到它。但是在汽車、飛機(jī)、航天器和大量的復(fù)雜設(shè)備方面卻不是這樣。 Forth 不需要這么復(fù)雜。經(jīng)典的 Forth 是從簡(jiǎn)單開(kāi)始的,它慢慢地被復(fù)雜所包圍。在 Forth Inc. 里,這都成了公司的文化。我們有了一個(gè)軟件包,我們銷售它、我們拓展它、我們鐘情于它。當(dāng)我離開(kāi) Forth Inc 之后,就有了一個(gè)簡(jiǎn)化的機(jī)會(huì), cmForth 就是成果。不幸的是 cmForth 并沒(méi)有廣泛應(yīng)用,所以我很難告訴你它能夠工作得多好。
在我的記憶中, ShBoom 與 cmForth 一樣好。我做的最大應(yīng)用是使視頻能夠工作并開(kāi)始客戶芯片設(shè)計(jì)包的過(guò)程,所以我知道使用 ShBoom 的捷徑。
i21 ,我現(xiàn)在使用的是帶顏色的 Forth ,還沒(méi)有用它做有效的應(yīng)用。它極端地簡(jiǎn)單,它比任何的前輩都簡(jiǎn)單。我想說(shuō)說(shuō)為什么。
i21 本身是一個(gè)簡(jiǎn)單的處理器,但也沒(méi)有做到可能的最簡(jiǎn)化,因?yàn)楹孟笪覀兡艹鍪圻@個(gè)處理器的唯一希望就是它的速度,所以我增加了許多的復(fù)雜性以滿足速度的要求。我希望我得到了某種平衡的理由。 500 MIPS 是一個(gè)誘人的速度。我們只能使這個(gè)速度保持片刻,但某一天它會(huì)變得平滑。問(wèn)題是沒(méi)有哪些應(yīng)用需要這樣的速度,或者說(shuō)沒(méi)有大量的處理器要求這種速度。它很難銷售。
我最近已經(jīng)看到的最有趣的應(yīng)用是 SETI 的家庭計(jì)劃,在這個(gè)計(jì)劃中,你可以從 Arecebo 網(wǎng)站上下載數(shù)據(jù)并在自己的 PC 機(jī)上處理兩個(gè)星期,然后把結(jié)果傳回去與研究機(jī)構(gòu)分享。所以一個(gè)快速的處理器可以很容易在那里銷售和應(yīng)用。可能 SETI 分布式處理器系統(tǒng)有一些事情可以做。
一但你得到了一個(gè)處理器,你希望它適合 Forth。之后, Forth 應(yīng)該怎樣開(kāi)發(fā)這個(gè)處理器呢?這個(gè)問(wèn)題引出了 Forth 是什么的問(wèn)題。我期待有人能夠告訴我答案。我不斷在問(wèn), Forth 是什么?
Forth 是高度因子化的代碼。我不知道除了說(shuō) Forth 是定義之外還能說(shuō)什么。如果你有了許多短小的定義,那你就是在編寫 Forth 程序。為了寫出許多短小的定義,你需要一個(gè)堆棧。堆棧并不流行,我很奇怪為什么它沒(méi)有流行。許多壓力來(lái)自于既得利益者,他們不喜歡堆棧,他們喜歡寄存器。堆棧并不是能夠解決所有問(wèn)題的一個(gè)概念,但它的確非常非常有用,特別是對(duì)于信息屏蔽,并且你需要兩個(gè)堆棧。
這些思想到現(xiàn)在已經(jīng)有 30 多年了,我已經(jīng)談?wù)撍鼈?30 多年了,可現(xiàn)在被人們接受的程度與 30 年前沒(méi)有什么差異,可能隨著工業(yè)的發(fā)展,對(duì)它們的關(guān)注反而是更少了。
Forth
?Defintions
?Stacks
這就是 Forth 。需要支持定義。
什么是定義?非常經(jīng)典的說(shuō)法是一個(gè)定義就是用冒號(hào)說(shuō)明一些事情、字、在什么地方結(jié)束定義等等
: some ~~~ ;
我總是試著通過(guò)縮寫來(lái)說(shuō)明其中的意義,不論你這里寫下的字串是為了更常用或者是更方便。但它并不嚴(yán)格地是縮寫,它可以有一個(gè)或者兩個(gè)參數(shù)。這里有一個(gè)程序員相關(guān)的問(wèn)題,也可能是與所有程序設(shè)計(jì)都有關(guān)的問(wèn)題:我們給一個(gè)子程序輸入了太多的參數(shù)。看看許多 C 語(yǔ)言程序,它們很可笑。程序中的每件事情都通過(guò)調(diào)用序列傳遞,而子程序只是一個(gè)啞巴。
一個(gè) Forth 字不應(yīng)該有多于一個(gè)或者兩個(gè)參數(shù)。人們處理堆棧時(shí)有這么多的麻煩來(lái)處理堆棧,絕對(duì)不應(yīng)該有多于 3 至 4 個(gè)元素的深度。
我們現(xiàn)在的具體做法是使一個(gè)字(:)以紅色顯示。通過(guò)這種方式你就不需要再使用冒號(hào)了,這不僅減少了你存儲(chǔ)源程序文本的大小,而且也使得后面的工作極為清晰。紅色的字是被定義的字:
some ~~~
定義是綠色的,在定義之中可以有一個(gè)分號(hào)表示返回,但是并不結(jié)束一個(gè)定義。如果需要,你可以有多個(gè)返回,你還可以有多于一個(gè)入口點(diǎn)。沒(méi)有冒號(hào)定義,這個(gè)定義就會(huì)落入另一個(gè)定義,并在下一處返回;我們已經(jīng)沒(méi)有表示編譯模式和執(zhí)行模式的狀態(tài)。你或者是在運(yùn)行綠色或者是在運(yùn)行白底黑字。黑色意味著執(zhí)行,綠色意味著編譯,紅色意味著定義。
這對(duì)我來(lái)說(shuō)更簡(jiǎn)單也更清晰,這是一個(gè)嶄新的概念,但是還沒(méi)有被廣泛接受,不過(guò)我們馬上就會(huì)看到。
但是對(duì)于堆棧來(lái)說(shuō),堆棧應(yīng)該很淺。在 i21 芯片上,堆棧只有 18 個(gè)元素的深度,這個(gè)尺寸的選擇是一個(gè)有效的數(shù)字。
處理這個(gè)堆棧的字是 DUP 、 DROP 和 OVER ,沒(méi)有別的了。 SWAP 也很方便,你需要它,但它不是一個(gè)機(jī)器指令。但是,我們沒(méi)有 PICK 和 ROLL ,沒(méi)有什么復(fù)雜的操作可以使你能夠按索引來(lái)訪問(wèn)元素。前兩個(gè)元素是你需要關(guān)心的堆棧部分。當(dāng)然。在一個(gè)芯片上,它們是兩個(gè) ALU 的輸入端,這也是硬件相關(guān)的。
其它的元素也在堆棧上,因?yàn)槟惆阉鼈兎诺搅四抢?#xff0c;你準(zhǔn)備以后當(dāng)堆棧回到那里時(shí)再處理它們。它們不在那里是因?yàn)槟阏谑褂盟鼈儭D悴幌攵褩I系臇|西太多,因?yàn)槟愫芸炀蜁?huì)忘掉他們的意義。
所以,那些畫(huà)堆棧圖示的人馬上應(yīng)該明白他們正在做著不正確的事情,哪怕是很常用的短小的圖示。這種方法是:如果你定義了一個(gè)字,你還寫上一個(gè)說(shuō)明來(lái)顯示堆棧的影響,比如說(shuō) F 和 x 和 y
F ( x - y )
過(guò)去,當(dāng)我把堆棧弄得太復(fù)雜時(shí)我也使用這種方法,但是現(xiàn)在不再這樣了。我們不需要這類的信息,它應(yīng)該能夠從源代碼中很容易地得到,或者應(yīng)該在另外的地方編寫文檔。
所以我使用的堆棧操作非常有限,而條件操作也是這樣,在經(jīng)典的 Forth 中我們使用 IF ELSE THEN ,現(xiàn)在我排除了 ELSE 。
我不認(rèn)為 ELSE 的用途能夠與介紹它的復(fù)雜性相比較,你可以通過(guò)我的代碼明白這一點(diǎn)。我將把 IF 和一個(gè)分號(hào)一起使用,我將在一個(gè)點(diǎn)上退出定義或者繼續(xù)。
IF ~~~ ; THEN
我有兩條分支,但是我用了“分號(hào)并不結(jié)束一個(gè)定義”的新特點(diǎn)。
還有循環(huán),有許多循環(huán)結(jié)構(gòu)。原來(lái)我使用的結(jié)構(gòu)來(lái)自于其它的語(yǔ)言,我想事情就是這樣發(fā)展的。它們是
DO LOOP 還有
FOR NEXT 還有
BEGIN UNTIL
DO LOOP 來(lái)自于 FORTRAN 語(yǔ)言, FOR NEXT 來(lái)自于 BASIC 語(yǔ)言, BEGIN UNTIL 來(lái)自于 ALGOL 語(yǔ)言。
我們?cè)?Forth 中選擇哪一個(gè)?這個(gè) (DO LOOP) 有兩個(gè)循環(huán)控制參數(shù),太復(fù)雜了。這個(gè) (FOR NEXT) 有一個(gè)循環(huán)控制參數(shù),非常便于硬件實(shí)現(xiàn),如果有足夠的硬件實(shí)現(xiàn)時(shí)它本身也非常簡(jiǎn)單。這個(gè) (BEGIN) 有可變數(shù)目的參數(shù)。不幸的是……(錄像帶雜音)
我們正在使用 iTV 的記錄設(shè)備,這是它的拱頂 (vault) 。如果你聽(tīng)到了一個(gè)回音,那是什么?那就是拱頂。
我得到了一個(gè)新的循環(huán)結(jié)構(gòu),它在 COLOR Forth 中使用,我覺(jué)得它比另外的那些都好。這種方法是:如果我有一個(gè)字 WORD ,我可以實(shí)現(xiàn)對(duì)這個(gè)字 WORD 的某種有條件的引用。這就是我的循環(huán)方式。
WORD ~~~ IF ~~~ WORD ;
?THEN ~~~ ;
我回到當(dāng)前定義的開(kāi)始 , 這就是我現(xiàn)在使用循環(huán)的唯一方法,它是足夠而方便的。它還有兩個(gè)邊際影響:一個(gè)就是它要求一種遞歸版本的 Forth, 這個(gè)字必須在當(dāng)前的定義中被引用,而不能夠要求被預(yù)先定義。這就省去了 SMUDGE/UNSMUDGE 概念, ANS 正準(zhǔn)備為這個(gè)概念找一個(gè)合適的名字。但是最終的結(jié)果是它更簡(jiǎn)單了。
對(duì)于嵌套的循環(huán)這種方法當(dāng)然很不方便,但是嵌套的循環(huán)畢竟是一個(gè)不確定的概念。你也可以有嵌套定義。你應(yīng)該條件化地執(zhí)行一個(gè)字,還是應(yīng)該有某種像 IF THEN 這樣的結(jié)構(gòu)?這個(gè)問(wèn)題我們已經(jīng)討論 15 年了。這里有一個(gè)例子,我想它說(shuō)得很明白,唯一的循環(huán)是必須重復(fù)一個(gè)字。
WORD ~~~ IF ~~~ WORD ;
?THEN ~~~ ;
如果你這樣堅(jiān)持做下去,能夠?qū)崿F(xiàn)更徹底的因子化。這是我頭腦中的 Forth 的關(guān)鍵,你因子化、再因子化、再因子化,直到你的大多數(shù)定義都只有一行或者二行長(zhǎng)。
(Jeff) 你也許指的是 WORD 之后的那個(gè)分號(hào)導(dǎo)致一個(gè)尾遞歸,可以把對(duì) WORD 的調(diào)用轉(zhuǎn)為跳轉(zhuǎn)。
(Chuck) 所以你沒(méi)有理由進(jìn)行一個(gè)調(diào)用,因?yàn)橹竽悴粫?huì)到任何一個(gè)地方,你用一個(gè)跳轉(zhuǎn)就可以了。實(shí)際上在我最近所有的 Forth 中,像分號(hào)一類操作的意義究競(jìng)是一個(gè)返回還是一個(gè)跳轉(zhuǎn)將依賴于上下文,其中的優(yōu)化是由編譯器完成的。那是一個(gè)很簡(jiǎn)單的回朔優(yōu)化,實(shí)際上是節(jié)省了重要的資源,那就是返回棧。
在我的 i21 中,返回棧的深度中只是 17 個(gè),使用這種嵌套結(jié)構(gòu)的人可能會(huì)遇到麻煩,你不能嵌套得太深,使得不可能再進(jìn)行下一步的程序設(shè)計(jì)。你也可以使用調(diào)用來(lái)得到像使用 GOTO 一樣的亂七八遭的代碼。你應(yīng)該保持簡(jiǎn)單。
這就是我能想起來(lái)的最近 Forth 所做的主要修改。可能 BLOCK 是個(gè)例外。 BLOCK 是一個(gè)有趣的塊訪問(wèn)字,用于訪問(wèn)磁盤的一個(gè)區(qū)。現(xiàn)在我把它定義成訪問(wèn)存儲(chǔ)器的一個(gè)區(qū)。沒(méi)有任何理由使用磁盤了,由于有了兆字節(jié)級(jí)的存儲(chǔ)器,你只需要把數(shù)據(jù)裝入存儲(chǔ)器,并從那里運(yùn)行就可以了。由于需要磁盤, BLOCK 這個(gè)字就變得非常非常地簡(jiǎn)單,基本的 BLOCK 定義是一個(gè)與 1000 的積:
BLOCK 1024 * ;
這就指定了你訪問(wèn)的存儲(chǔ)器是 1024 字節(jié)寬。 BLOCK 的值是你為存儲(chǔ)器所做的分區(qū)值,它把你的存儲(chǔ)器因子化成可管理的片斷,你可以認(rèn)為存儲(chǔ)器是由一個(gè)兆字節(jié)所組成的,也可以認(rèn)為是由幾千個(gè)塊所組成的。
我看過(guò) NASA 的一個(gè)網(wǎng)頁(yè),現(xiàn)在想起來(lái)還很有趣。它說(shuō)宇宙飛船的速度是每小時(shí)110,000 公里。因?yàn)槲覍?duì)這樣的數(shù)字沒(méi)有什么感覺(jué),覺(jué)得如果把它轉(zhuǎn)換成每小時(shí)69,000英里可能就會(huì)好一些。不過(guò),這些數(shù)字對(duì)于普通人來(lái)說(shuō)還是沒(méi)有什么意義。我想應(yīng)該把它轉(zhuǎn)換成每秒多少公里或者其它我們能夠感覺(jué)到的更小的數(shù)字。當(dāng)我們使用 120M 字節(jié)的存儲(chǔ)器時(shí),使用這么大的數(shù)字不會(huì)有什么好處,它只不過(guò)是一個(gè)很大的數(shù)字而已,雖然令人印象深刻,但并沒(méi)有什么用。所以 BLOCK 可以為我們進(jìn)行適當(dāng)?shù)亩?biāo)。
一個(gè)說(shuō)法是 Forth 完全由程序員來(lái)決定。我愿意把這理解成 Forth 程序員應(yīng)該做些什么。我發(fā)現(xiàn)教給了某人 Forth 語(yǔ)言,并不意味著他就是一個(gè)很好的 Forth 程序員了。在你能夠進(jìn)行有效的工作之前,有一些 Forth 形式和語(yǔ)法之外的東西已經(jīng)嵌入到你的頭腦中了。
我的觀點(diǎn)是:我看到的每一個(gè)應(yīng)用,只要不是我自己寫的,它的代碼量就會(huì)是它實(shí)際需要的 10 倍。我也看到 Forth 程序員正在用所需要代碼量的 10 倍長(zhǎng)的代碼來(lái)編寫應(yīng)用程序。
我所關(guān)心的,我這幾年一直深思的問(wèn)題是:我怎么才能說(shuō)服這些人編寫好的 Forth ?我怎么才能告訴他們說(shuō)編寫好的 Forth 程序是可能的?為什么人們編寫的程序是他們需要編寫的 10 倍?
微軟是這樣做的,我想大家都知道,但是他們至少還有一個(gè)理由就是他們必須與任何以前所做的事情相兼容。如果你不能從一張清晰的白紙開(kāi)始,那么你就得寫更多的代碼。但是需要 10 倍的代碼嗎?好象是太多了。
一個(gè)程序應(yīng)該有多大?例如, TCP/IP 協(xié)議棧應(yīng)該有多大?我不知道。在我坐下來(lái)編寫代碼之前我不知道。但是它不應(yīng)該很大,大約 1K 字就可以了。
i21 的每個(gè)字有 4 個(gè)指令。奔騰計(jì)算機(jī)每?jī)蓚€(gè)字節(jié)一條指令。這很難判斷。你應(yīng)該討論指令而不是指令駐留的存儲(chǔ)器的大小。
看來(lái)大約有 1000 條指令就能夠讓我做任何事情,所有的程序都應(yīng)該是 1000 條指令長(zhǎng)。
你怎么做得到呢?這里面有什么訣竅?你怎樣使應(yīng)用程序很小?這里有幾件事情是在任何情況下、使用任何語(yǔ)言都應(yīng)該小心地去做的:
沒(méi)有鉤子
第一件事就是沒(méi)有鉤子。不要留一個(gè)接口,想著未來(lái)的什么時(shí)候當(dāng)問(wèn)題變化時(shí)插入一些代碼,因?yàn)閱?wèn)題會(huì)以你不能預(yù)見(jiàn)的方式變化。反正這個(gè)成本肯定是浪費(fèi)了。不要預(yù)測(cè),只解決你眼前的問(wèn)題。
不要復(fù)雜化
簡(jiǎn)化你遇到的問(wèn)題,至少不要使它變得復(fù)雜化。我自己就是這樣做的,很有趣。你遇到了一個(gè)令人厭煩的問(wèn)題,在它之后是一個(gè)更有趣的問(wèn)題。所以你應(yīng)該為更有趣的問(wèn)題編寫代碼,你所遇到的只是它的子集,它是微不足道的。但是,如果你努力地為這種微不足道的問(wèn)題編碼,那就當(dāng)然地為你所需要解決的問(wèn)題編寫了相當(dāng)于實(shí)際需要 10 倍的代碼。
10 倍的代碼意味著 10 倍的成本;編寫的成本,文檔的開(kāi)銷,存儲(chǔ)器的開(kāi)銷,磁盤的開(kāi)銷,編譯的開(kāi)銷,裝入的開(kāi)銷。你所做的每件事情都要貴 10 倍。實(shí)際會(huì)更壞,因?yàn)閺?fù)雜度是按指數(shù)增加的。
10x 代碼
10x 成本
10x 錯(cuò)誤
10x 維護(hù)
10 倍的錯(cuò)誤! 10 倍的維護(hù)困難在 Y2K 問(wèn)題上給出了很好的說(shuō)明。奇怪的是我看到人們都在用 COBOL 解決 Y2K 問(wèn)題,把程序明顯地變得更復(fù)雜、更大、引入了更多的意大利面條式的代碼,這些代碼更不可維護(hù)。如果他們是使用 Windows ,那么 50 年之后,應(yīng)用會(huì)再次崩潰。程序員們并不是擴(kuò)大日期的范圍,而只是移動(dòng)它,所以在 Windows 運(yùn)行到盡頭的時(shí)候,它就會(huì)產(chǎn)生另一個(gè)問(wèn)題。
這就是我們至今還在運(yùn)行 10 年或者 20 年前老程序和為什么人們沒(méi)有錢去更新、理解和重新編寫這些程序的原因。因?yàn)樗鼈兲珡?fù)雜了,比它們本來(lái)所應(yīng)該有的程度復(fù)雜了 10 倍。
所以,你如何避免這個(gè)陷阱?你如何編寫 1 倍的程序?
1 倍, 1x 應(yīng)該是一個(gè)網(wǎng)頁(yè)的名字
你因子化、因子化、因子化、因子化,你扔掉了所有不使用的東西、不合理的東西。
Forth 的全部在于你不能用 Forth 來(lái)編寫程序,而是用 Forth 來(lái)編寫字典。當(dāng)你設(shè)計(jì)一個(gè)應(yīng)用的時(shí)候,你寫出 100 個(gè)左右的字,它們可以描述應(yīng)用,然后你使用這 100 個(gè)字寫出一行定義來(lái)解決應(yīng)用的問(wèn)題。找到這 100 個(gè)字并不容易,但它們是存在的,它們總是存在的。
讓我給出一個(gè)應(yīng)用程序的例子,在這個(gè)例子中你不僅能夠減少 90% 的代碼,而且有一個(gè)情況可以減少 100% 的代碼。這個(gè)例子就是我們熟悉的文件。如果你在應(yīng)用或者 Forth 系統(tǒng)中使用文件,你差不多有這樣一些字:
OPEN CLOSE READ WRITE REWIND 等等
它們可能不是這么短的字,比如,像在 Windows 中 OPEN-FILE 。如果你覺(jué)得這些都不需要,那你將節(jié)省實(shí)現(xiàn)文件系統(tǒng)代碼的 100% 空間。文件系統(tǒng)在一個(gè)典型的應(yīng)用程序中并不是一個(gè)大個(gè)子的部分,但它是一個(gè)不常見(jiàn)的無(wú)用部分。確定了你要做的方面,說(shuō)出了我們不需要做事情。我們不需要在校驗(yàn)和頂上再來(lái)做一次校驗(yàn)和。我們不需要編碼加密因?yàn)槲覀兏揪筒恍枰獋鬏斎魏螙|西。你可以省去所有這些事情。
你現(xiàn)在看到的是一個(gè)全世界所有的程序員所遇到的所有問(wèn)題的一個(gè)解,這個(gè)解是通用的,但是沒(méi)有任何人會(huì)遇到通用的問(wèn)題。
我希望我告訴你的話能夠使你寫出好的 Forth 。我可以證明。我已經(jīng)證明了應(yīng)用程序代碼可以減少 90% ,在某些情況下可以減少 99% ,我可以做,但是需要一個(gè)案例一個(gè)案例地做。我一直找不到一般性的原理。
(Jeff) 我有一個(gè)問(wèn)題是有關(guān)你 COLOR Forth 屏幕的。人們已經(jīng)注意到你在屏幕上使用了很大的字體,但是只有較少的信息。它多少是由于你的視力?你每次看的時(shí)候有多少的信息受到限制?
(Chuck) 我對(duì)小字體越來(lái)越?jīng)]有耐心,幾乎不能閱讀網(wǎng)頁(yè)。直接去看那些字符模糊不清,戴上眼鏡看,它們還是模糊不清。如果加大字體,這有時(shí)能夠做到,有時(shí)做不到,會(huì)失去一些上下文。這是一個(gè)問(wèn)題,可能對(duì)于大眾中不斷增加的群體來(lái)說(shuō)都是一個(gè)問(wèn)題。所以我盡量地使用大的字符,但是如果你把它們弄得太大,那你就會(huì)丟失信息。
現(xiàn)在一個(gè)用于設(shè)計(jì)幻燈片翻頁(yè)的經(jīng)典規(guī)則是你拾取一幀然后在其中放入一些主題,你不能在一張幻燈片上放太多的內(nèi)容,否則你的聽(tīng)眾就會(huì)糊涂,如果你使用太小的字符,人們就不可能閱讀這些內(nèi)容。
在 COLOR Forth 的情況下,我想字符也可能太大了。我可以一次在一個(gè)屏幕上得到 256 個(gè)字符。根據(jù)所使用計(jì)算機(jī)的不同,我可以得到 20x14 或者有時(shí)是 24x15 。這就足夠了。在 256個(gè)字符中,我得到的信息大約與過(guò)去 1024 字節(jié)得到的信息一樣多,因?yàn)槲覜](méi)有進(jìn)行格式化,甚至沒(méi)有任何的換行。在我的屏幕上充滿字符。
一個(gè)原因是我想探究彩色字的價(jià)值,如果我有一些帶顏色的字,那么不同的顏色將如何工作?我發(fā)現(xiàn)它們做得好極了,我不需要用定義字來(lái)格式化它們。當(dāng)然,實(shí)際上并不好看,因?yàn)樵谄聊坏淖筮吅孟笥幸粋€(gè)紅墻,如果你也使用這種方式,那就不一定非使用紅色不可。
我覺(jué)得你在做一個(gè)網(wǎng)頁(yè)時(shí)也應(yīng)該使用這種哲學(xué)。在網(wǎng)頁(yè)上放入盡量少的信息,只要能把你想告訴人們的事情說(shuō)清楚就可以了,不要弄得費(fèi)話連篇。另一方面是不要在頁(yè)面上放一個(gè)索引。你只應(yīng)該放入真實(shí)的信息,你需要把重要的信息加亮,你需要使它清晰和可讀。
要改變我的字體比較困難。我使用 32x32 像素點(diǎn)。下一次我可以使用 24x24 像素點(diǎn)試一試。
這種格式的應(yīng)用程序很少是一個(gè)屏幕。一個(gè)應(yīng)用程序大約是 2 個(gè)或者 3 個(gè)屏幕長(zhǎng),這與我在一個(gè)上下文中為一個(gè)應(yīng)用程序所寫的代碼相當(dāng)。
例如,我有一個(gè)應(yīng)用程序,它把一個(gè)特殊芯片性能的譜顯示在屏幕上。這是一個(gè)漂亮的顯示,對(duì)于把信息表示成可理解的方式是一個(gè)很好的練習(xí)和重要的方法,如果以后你有機(jī)會(huì)看到它的演示,那一定是很有趣的。
小的應(yīng)用程序。應(yīng)用程序不是適當(dāng)?shù)淖?#xff0c;小的代碼只做特別的事情,從來(lái)都不做通用的事情。
Jeff 使我想起了 Machine Forth 的另外一些概念。 Machine Forth 是一個(gè)我很愿意回憶的 Forth ,它使用在機(jī)器中構(gòu)建的 Forth 原語(yǔ)來(lái)做一些事情而不是使用解釋器版本或者宏定義來(lái)做這些事情。這些事情之一就是 IF 。
經(jīng)典的 IF 去除留在堆棧上的東西,這在 i21 上實(shí)現(xiàn)并不方便,所以 IF 把它的參數(shù)留在堆棧上,于是你就不得不經(jīng)常寫類似 IF DROP 這樣的結(jié)構(gòu),但也不總是這樣,看起來(lái)似乎方便和不方便各占一半。它不再使用 DUP IF 或者 ?DUP ,也就是說(shuō)有了這種方便性,就不用 ?DUP 了。 ?DUP 并不是個(gè)好詞,它在堆棧上留下了不同數(shù)目的東西,做這樣的事情很不明智。
IF
-IF
除了 IF 之外, Machine Forth 還有一個(gè)判斷 -IF 。這個(gè)字用于測(cè)試 0 ,那個(gè)字只用于測(cè)試符號(hào)位。我想你可能經(jīng)常需要根據(jù)一個(gè)數(shù)是正還是負(fù)的來(lái)進(jìn)行決策。但它并不是以那種方式工作的。在 COLOR Forth 中,我甚至不關(guān)心它怎么使用。
在過(guò)去的二十年中,世界已經(jīng)發(fā)生了明顯的變化,但我想沒(méi)有人能夠預(yù)測(cè)出來(lái),當(dāng)我 50 年代第一次開(kāi)始工作時(shí),只有 7 臺(tái)用于計(jì)算的計(jì)算機(jī)。那時(shí)的計(jì)算機(jī)總是用來(lái)解決又大又長(zhǎng)的算術(shù)表達(dá)式。我們所做的因子化工作就是把這些事情因子化,使得這些不必重復(fù)計(jì)算,它就可以運(yùn)行得更快,那就是 FORTRAN 語(yǔ)言的全部觀點(diǎn)。這種傳統(tǒng)甚至到了今天還在影響著我們。
我沒(méi)有做過(guò)統(tǒng)計(jì),但是我猜想今天的計(jì)算機(jī),絕大多數(shù)都不是用來(lái)做計(jì)算的,而是在移動(dòng)字節(jié)。如果你有一個(gè)瀏覽器,這個(gè)瀏覽器除了一次性地計(jì)算機(jī)屏幕的大小外,幾乎不進(jìn)行什么計(jì)算。查看一個(gè)數(shù)的符號(hào)的概念可能并不像我想的一樣有用,幾乎所有的數(shù)都是正數(shù),并不需要查看它們的符號(hào)。基于同樣的原因, Machine Forth 沒(méi)有減法操作。我把減法處理成 1 的補(bǔ)碼。
- one comp
這種做減法的方式并不方便。但是對(duì)于今天的應(yīng)用來(lái)說(shuō),實(shí)現(xiàn)協(xié)議或者顯示文本,算術(shù)運(yùn)算是不需要的。一個(gè)計(jì)算機(jī)不應(yīng)該為算術(shù)運(yùn)算進(jìn)行優(yōu)化,我的計(jì)算機(jī)也不是。
另一方面,為了數(shù)據(jù)傳輸方面的優(yōu)化,實(shí)現(xiàn)一個(gè)增量存取操作就很有用。地址是在任何計(jì)算機(jī)上都有的問(wèn)題,但在 i21 上這是一個(gè)更特別的問(wèn)題。在 i21 上,地址是一個(gè) 20 位的數(shù),為了裝入一個(gè)地址,你最好做一個(gè)文字常量的取,它可以取出 20 位的擴(kuò)展字。需要一個(gè)附加的存儲(chǔ)器裝入周期,之后你可以進(jìn)行存儲(chǔ)器讀取,這又需要另外一個(gè)存儲(chǔ)器周期。所以地址的處理非常昂貴,你應(yīng)該盡力使它最小。取加 (@+) 操作字對(duì)此有所幫助。你把一個(gè)地址放入地址寄存器中,然后它就存在那里。如果你執(zhí)行 @+ , A 將被增量,你就可以連續(xù)地讀取后面的內(nèi)容了。同樣,你也可以存入一串東西。當(dāng)然在需要的時(shí)候,你還有不進(jìn)行增量的取 (@) 和存 (!) 操作。
在經(jīng)典的 Forth 系統(tǒng)中并沒(méi)有這些操作,我想在標(biāo)準(zhǔn)中也沒(méi)有提及。它們導(dǎo)致了一種完全不同的程序風(fēng)格。在 DO LOOP 的情況下,最有效率的事情就是把實(shí)際的地址作為循環(huán)參數(shù),然后通過(guò)字 I 讀出它,在循環(huán)內(nèi)部進(jìn)行對(duì) I 的取 (I @) 。 DO LOOP 與地址一起工作,如果你做這些,如果你使用讀加操作 (@+) ,那你就不需要 DO LOOP 了,你也不需要 I 了,你在循環(huán)中使用讀加 (@+) 就可以每次讀出不一樣的事情,它們不同但是等效。你可以把一個(gè)轉(zhuǎn)換成另一個(gè),方便地讀取那些地址在 A 寄存器中的東西。
在 MOVE 的情況下,你想把某些東西從存儲(chǔ)器的一個(gè)區(qū)域移動(dòng)到另一個(gè)地方,你就需要兩個(gè)地址,因此作為地址的值存儲(chǔ)在 R 寄存器中,因?yàn)橹挥性谝粋€(gè)上下文中你才可能把地址放到 R 寄存器中,它有一個(gè)自動(dòng)增量能力。所以我基本上有對(duì)于 A 的取加 (@+) ,對(duì)于 R 的取 R 或者存 R ,你可以有效地進(jìn)行 MOVE 。
這就引出了另一個(gè)問(wèn)題。 A 除了作為地址寄存器使用外,它還非常像一個(gè)局部變量,你可以在其中存一些東西,過(guò)一會(huì)兒再讀出來(lái)。把它作為一個(gè)地址寄存器的原因和我使用它的原因是一樣的,從字面上講,它為地址訪問(wèn)提供了一個(gè)機(jī)制( (@+) 。從程序員的角度看,它比放在堆棧上的地址更方便。但是如果你準(zhǔn)備反復(fù)地訪問(wèn)這個(gè)寄存器,就必須把它放在一個(gè)你可以對(duì)它進(jìn)行增量的地方。為了放置它你必須訪問(wèn)那個(gè)寄存器,如果你能夠做到這些,你就可以使用這個(gè)寄存器做別的事情,就像你使用返回棧做別的事情一樣。
不同之處是如果你把一些東西放到返回棧上,還必須記著把它拿下去,對(duì)于 A 寄存器就不用這樣了。有人試著把 A 作成一個(gè)堆棧,使得你可以把一些東西 PUSH 進(jìn)去或者 POP 回來(lái),是不是值得這樣做并沒(méi)有一個(gè)明確的答案。肯定需要更多的指令去訪問(wèn) A 。你希望 DUP A ?你需要 DROP A ?現(xiàn)在這種 A 的方式是最容易的。
我也許還需要一個(gè)寄存器稱為 M ,可以在 40 位的乘法中保存一個(gè)乘數(shù)。但是我的系統(tǒng)中并沒(méi)有足夠多的乘法要做,所以這件事還沒(méi)有成為現(xiàn)實(shí)。
但這樣一個(gè)寄存器卻引出了一個(gè)局部變量的問(wèn)題。有許多關(guān)于局部變量的討論,這是在你的應(yīng)用中能夠節(jié)省 100% 代碼的另一個(gè)方面。我堅(jiān)信局部變量不但沒(méi)有用,而且很有害。
如果你正在編寫需要使用局部變量的代碼,那么你就是在寫……非優(yōu)化的代碼?不要使用局部變量。不要出現(xiàn)新的語(yǔ)法來(lái)描述它們,不要出現(xiàn)新的策略來(lái)實(shí)現(xiàn)它們。如果你有局部寄存器你就可以使得局部變量很有效,但是不要這樣做。它不好。它是錯(cuò)誤的。
變量是必要的。 COLOR Forth 需要許多的系統(tǒng)變量,當(dāng)你編輯某些東西的時(shí)候,光標(biāo)位置變量也非常有用。當(dāng)你回到光標(biāo)位置的時(shí)候,因?yàn)樽兞康闹颠€在那里,所以你就能夠回到原來(lái)的位置。變量很有用,我沒(méi)有看到任何只使用少數(shù)變量的情況,也沒(méi)有看到使用瞬時(shí)訪問(wèn)變量的情況。
聰明、解釋堆棧圖、給一個(gè)字命名,這些都是練習(xí)。你可以進(jìn)行所有這些游戲。我想 Forth 程序員可能用他們已有的工具進(jìn)行了太多這方面的游戲,因?yàn)闆](méi)有應(yīng)用。如果一個(gè) Forth 程序員能夠更多地關(guān)注應(yīng)用程序而不是更新工具,那就更好了。
對(duì)于我來(lái)說(shuō),一個(gè)應(yīng)用程序就是 Web 瀏覽器。如果你無(wú)事可做,那就寫一個(gè)瀏覽器。 Netscape 并沒(méi)有完成這件工作,沒(méi)有做到它應(yīng)該能做到的樣子、沒(méi)有實(shí)現(xiàn)它應(yīng)該有的功能,。事實(shí)上 Netscape 和 Microsoft 都從 Mosaic 那里借用了大量的東西,它們看起來(lái)就像是孿生的東西。如果還是用同一種語(yǔ)言編寫的,那種語(yǔ)言就是 FORTRAN 。
寫一個(gè)新的瀏覽器。這是一個(gè)很好的應(yīng)用。它能夠使你訪問(wèn)信息世界,我將在業(yè)余時(shí)間關(guān)注這個(gè)好應(yīng)用。
感謝各位的收聽(tīng)。
總結(jié)
- 上一篇: POS收银系统报EFI Shell ve
- 下一篇: 服务器主机是什么系统版本,服务器主机是什