這個奇葩的語言,代碼寫完后連作者自己都看不懂了!
周末的Hello World咖啡館依然熱鬧非凡,Java,Python,Lisp等一伙人坐在一起談笑風生。這時候Java注意到門口來了一個面色陰郁的老頭兒,在咖啡館門口徘徊著,似乎不愿意進來。
Java上去詢問, 老頭兒說他叫Forth,被主人設計成了一幅古怪的模樣,現(xiàn)在沒有多少程序員愿意用了,失去了往日豐厚的收入,只有流落街頭。
Lisp笑道:“你坐什么來的?”
老頭兒說:“騎電動車。”
“我們坐的都是奔馳、勞斯萊斯,你騎電動車!你騎電動車Hello World咖啡館都不讓你進來啊!”
Java邀請老頭兒入座:“別聽Lisp胡扯,你說說,你被設計成了什么古怪模樣?”
Forth 說:“我被設計成了一個基于棧的編程語言,你看看,比如你要計算 3 + 4 . ,得這么來......”
Forth說著從懷里掏出了幾張漫畫。
(第一步:把數(shù)字3入棧)
(第二步:把數(shù)字4入棧)
(第三步:從棧中取出4和3, 執(zhí)行3+4, 把結(jié)果7 入棧)
(第四步:從棧中取出數(shù)字7, 在屏幕上顯示)
(圖片來源:https://www.forth.com/starting-forth/1-forth-stacks-dictionary/)
Java 一看就樂了:“哈哈,漫畫不錯啊,這不和我Java是一樣的嗎?我也是基于棧的虛擬機啊。不信你看看碼農(nóng)翻身介紹我的文章《我是一個Java Class》。”
Python也樂了:“沒錯,我也是基于棧的虛擬機,咱們的工作方式是一樣的。”
Forth疑惑的問道:“是嗎?難道你們也是如此? 是不是還有很多程序員在雇傭你們啊?我看你們樂呵呵的,穿著光鮮亮麗,開豪車,工資不低吧?”
“一般一般,富裕談不上,最多是個小康。既然咱們差不多,你怎么這么落魄啊!” Java問道。
“唉,我還沒有給你說我的編程語法呢, 比如你要計算(3+4)* 5 ,程序員得這么寫:”
3 4 + 5 *
Java和Python都大吃一驚:“難道今天遇到傳說中的后綴表達法了? 這種寫法可就太讓程序員崩潰了。”
只見Lisp撇撇嘴:“小樣,這就崩潰了,比我的前綴表達式差遠了 (* (+ 3 4) 5 ) ”
Java不動聲色:“那你如何定義一個函數(shù)呢?比如這個計算平方的函數(shù) ”
- public int square(int x){
- return x * x;
- }
Forth說:“在我這里不叫函數(shù),叫Word, 程序員需要這么定義。”
- : SQUARE DUP * ;
(注:冒號表示開始定義,分號表示結(jié)束定義)
Java看到了熟悉的DUP,說到:“你這里也有DUP啊,我的字節(jié)碼指令也用到了,它是把棧頂?shù)脑貜椭埔环荩賶喝霔V校? 但是你這里怎么沒有參數(shù)啊?”
“你這么快就忘了,我是一個基于棧的編程語言啊,參數(shù)會被放到棧中啊, 比如你想計算10的平方,需要這么調(diào)用:10 SQUARE, 展開后就相當于 10 DUP *”
10 先被壓入棧中,DUP會把棧頂?shù)脑貜椭埔环荩賶喝霔V小_@樣棧中就有兩個數(shù)字了,都是10 , 最后再調(diào)用乘法。
看到Java略有驚訝,F(xiàn)orth說:“這還不算什么, 你看看我的IF語句。”
: ?Negative 0 < IF ." less than 0" THEN ;
這是測試一個數(shù)字是不是小于0
-3 ?Negative 會輸出 less than 0。
Java忍不住說到:“我去,有點變態(tài)啊,我的腦子中得時刻想著有一個棧,所有的操作都是基于這個棧的!”
Forth有點驚訝:“你不是說你是基于棧的虛擬機嗎?怎么?和我不一樣嗎?”
“我們的虛擬機確實是基于棧的,但是我們的語法可是正常的語法啊 !程序員寫的時候,用的是最熟悉的中綴表達式。”
( 3 + 4 ) * 5 ;
“還有函數(shù)調(diào)用,也是符合直覺的,編譯成字節(jié)碼以后,才會在基于棧的虛擬機上執(zhí)行,有很多不求甚解的程序員都不知道我是基于棧的虛擬機!”
- square(30);
- is_negative(-3);
Python向Forth投去了同情的目光:“你的主人是怎么想的?讓程序員在編程的時候,時刻記住有個棧的存在,多累人啊!”
“我主人說了,基于棧的編程語言非常容易實現(xiàn),所以非常適合那些內(nèi)存很小/計算能力受限的計算機,對了,你知道打印機所使用的PostScript嗎?它也是基于一個基于堆棧的編程語言。”
大家都表示對PostScript不熟。
Forth說:“我舉個更簡單的例子,比如表達式計算吧,如果用你的中綴表達式 (3+4)* 5 ,你在實現(xiàn)的時候得先做詞法分析,然后做語法分析,形成抽象語法樹,必須考慮優(yōu)先級問題。”
Java說:“難道不應該這樣嗎?形成抽象語法樹(AST)是個通用操作啊。”
Lisp馬上插嘴:“AST大法好,你看我的前綴表達式,天然就是抽象語法樹啊, (* (+ 3 4) 5 ) , 我的代碼和數(shù)據(jù)的表示方式是一樣的,代碼可以被當作數(shù)據(jù)來修改...... 算了,說了你們也聽不懂。”
Forth說:“我就不用這樣,你看用后綴表達式,再加上棧,可以直接計算,多方便。”
Java感嘆道:“編譯的過程包括詞法分析,語法分析,語義分析。我看你的程序甚至不用做語法分析,只要做一個詞法分析,也就是分詞,然后就可以直接計算了!”
“是啊,我的語法非常簡單,或者說幾乎沒有什么語法,我的主人說我可能是世界上最簡單的語言了!”
Java 問道:“既然你這么簡單,怎么沒有流行起來啊?”
“這個......其實也不能算簡單,無論是編寫程序還是閱讀程序,腦子中時刻得想著那個棧,對程序員自身的思維水平要求太高,一般人是受不了的, 有人笑話我是一個write-only的語言,寫完以后連作者自己都讀不懂了。”
這幾個人都笑了起來。只有Lisp在撇嘴:這還要求高,你還沒見過我的宏......
Forth 喝了一杯咖啡,顫巍巍地站起來,騎上門口的自行車,一溜煙地離開了。Java 注視著他的背影,心中感慨,這個Forth是一個老兵,他和Lisp一樣,那種“古怪”的表達方式對廣大程序員來說都不太友好,想流行起來很難啊。編程語言就是這樣,沒有完美的東西,有所得必有所失啊。