這一篇文章我隻想和大家侃侃程式設計語言的事情,不會被放到書中。是以可以天南地北地扯淡,不用像前幾篇一樣畏首畏尾的了。
經過前面幾篇文章的讨論,已經把用純 c 語言來實作一個解釋器的方法介紹完了。但那些是寫給我校 c 語言初學者看的,并不隻是你,我得也覺得很不過瘾 ^_^。是以準備繼續深入學習編譯原理等課程,希望有志同道合的朋友和我一起交流!
在前幾篇文章中一直在鼓吹我拍腦袋想出的語言四大要素:“記憶體管理”、“表達式求值”、“輸入/輸出”、“按條件跳轉”,在這篇文章中您就姑且信一回當它是真的。按照這四條準則去比對,彙編語言是完全符合的。那為什麼又需要 c 語言、java、c# 等進階語言?這是因為程式設計除了需要“語言”之外還需要“抽象”!
“抽象”是個很有效的工具,相信你在為别人介紹自己房間時不會具體到每個木纖維、油漆分子和鐵原子。同樣的,我們也不樂意總是寫一堆 jnz、jmp 指令,而僅僅是為了實作 if、for、while 等控制結構。c 語言等進階語言提供的抽象的層次更高、表現力更強,允許用更少的語句描述更多的操作。感謝如此富饒的語言為我們帶來不同的視角去審視這個世界。
進階語言相較于低級語言屬于更高地抽象層次,進階語言之間的差别主要展現在适用範圍上。比如一些語言适合寫 web 程式,另一些适合做數值分析等。術業有專攻,你隻需根據自己的問題來選擇一門合适的語言。
當我們碰到一類新的問題時,首先考慮的就是定義新的資料結構,并設計多個函數去操作它,最後将它們獨立出來打包成一個類庫友善在其他地方調用(比如處理圖形圖像的 opengl 庫)。上面已經提過,每種語言都有它适合的領域,強行将一門語言用在它不擅長的領域中就出現冗長、繁瑣的代碼。自然語言也是如此:英語中有種文法叫虛拟語氣,描述的是一種假設,并非事實。比如“if i have time, i will go to see you. ”。如果按原意一字不差地翻譯相信會很繁瑣,我知道台灣作家痞子蔡在使用中文式的虛拟語氣很有一套:
如果我還能活一天, 我就要做你的愛侶。 我能活一天嗎?可惜。 是以我不是你的愛侶。 ——《第一次親密接觸》
上面是一段完整表現虛拟語氣精髓的話,相信在生活中我們不會這麼羅嗦。同樣的,如果你發現用現有語言來描述某個特定領域問題時顯得力不從心,就可以考慮為這個領域定制一種特定的語言了(domain specific language)!使用現成的詞法分析器和文法分析器(比如 lex 和 yacc)對提高開發效率很有幫助,但你也可以考慮采用像 rebol 這樣的語言設計一個“方言”,這會更簡單。如果你對 dsl 或 rebol 有興趣,可以加入阿裡旺旺 rebol 群(16626148)和蔡學镛前輩交流,他是這方面的專家。
從寫解釋器這件事中可以獲得一些建議:不要再争論哪個語言更優秀,隻有最适合的;用進階語言寫代碼首先力求可讀性好。第一條建議我在以前讨論“工具理論”時提過很多次,就不再重複,主要交流一下可讀性的問題。
在你自己實作過解釋器後希望也能明白,如果真有哪個解釋器執行語句“i++;”的效率比“++i;”低,那隻能說明這個解釋器寫得爛!像現代的 c 語言編譯器都會有優化的選項,編譯時去識别一些常見的熱點進行優化,難保那些自以為是的優化反而将代碼破壞得連編譯器也無法識别。是以要遷就解釋器而将代碼改得亂七八糟,我甯可換一個更好的解釋器!