對一些程序員來說,中文編程是一個很有意思的題目,這種思維有民族情緒作怪,也有“爲什麽不能”的冒險意識,以及切實對用母語思維的優勢的體認。
要設計一門好的中文編程語言除了要能擺弄編譯原理等等,還需要對母語本身有較深的理解。以前易語言的什麽“循環容器首”,是比較失敗的典型。除了語感,方塊字對排版的要求和線形文字也不盡相同。
中文化JS的雛形很早就有,這次有長假,把它實現了。現在回顧一下它的設計得分處和取捨原因。
1. [[]] 符號。在拉丁字母中,[ ] 就已經可以很好的框定一段文本了。但是在大段的中文中,[ ] 很不起眼。使用【】可以較明晰的區分,但是這個符號過於粗重,現代感不足。最後,我採用了兩個 [[ 形成組合符號 [[ ]],但是也仍然兼容【】。此外,{ } 在一堆中文中也無法體現自己的曲綫美,相反,頗有不倫不類之感。所以,凡是用 { } 的場合,都全部使用了 [[ ]],也就是說,語句塊,對象立即量和數組一樣使用了 [[ ]]。絕大部份情況都很完美。不過也有兩個歧義,語句塊中不使用分號結尾時和數組有歧義、空對象和空數組有歧義。對於第一個歧義,我要求語句必須用 ; 作為結尾。js語句末尾可自由選擇用 ;或不用;,這個特性大家詬病的已經很多,不如強制必須用 ; 。對於第二個歧義,我設計了 [[ : ]] 的敘述形式來表達 { },這樣就避免了和 [ ] 的衝突。 同樣的原因,我使用 # 作為屬性引用,而不使用找不到的 .
2. “如果”還是“若”。在中文編程中,如果追求字數少,可以用一些文言風格的表述,比如if對應為若,可以節省一些文字,看起來也較為文雅。不過我以為這樣容易形成文字障,妨礙思考,所以我採取一般的白話文敘述。
3. 如果 expr [[ ]]。 在c中,if() 後,可以是語句,也可以是語句塊,表面上看這樣一可以體現語句塊和語句的等當性,二來如果是單個語句,書寫可以簡單不少,但是實際編程中,我們經常需要把開始占到了便宜的語句又變成語句塊,這種事情發生太多,所以不如規定 if 後只能是語句塊,如果這樣規定後,if 的 () 就可以省略了!這樣一來,倒成全了真正的便利。和 basic 的 if 相比也不遜色了。while 等也做了這樣的處理。
4. if while switch 全部使用“如果”。對於中文來說,像這種條件判斷的場合,找任何富有創意的措辭都是很怪異的。不如全部使用“如果”,while 寫為 如果 cond 反復 [[ ]] 就很好理解了。類似的 switch 使用 如果 也很漂亮。
5. 函數聲明使用 函數頭 :: [[ ]]。 是否需要一個單獨的“函數”關鍵字,我認為erlang式的函數聲明要更形式化,而 function xxx 看上去就像 姓名張三 民族 漢 這樣,充滿了表單氣息,顯得思維不夠流暢。使用函數頭 :: 方式聲明函數,在編碼過程中,有兩個便利的用法:1) 先寫函數調用,再複製函數調用,加上 :: 直接定義函數。2)用 home end 鍵複製函數頭,直接作為調用。這種編碼過程中的工具優勢,是設計語言的人需要細心理解的。至於爲什麽不使用 :,而使用兩個 :,原因和使用 [[ 一樣,是為形成較顯眼的排版,也順便呼應了 c++ 式的類。為何不使用 ->,也是中文版式美觀決定的。在大段中文中 -> 的力度太薄弱了。
6. 匿名函數。匿名函數本來可以盡力做到 (args) :: [[ ]]。但匿名函數常出現在函數調用裡作為參數,在中文排版時,密集的 ( ) 會導致閱讀障礙。所以,我設計成像 erlang 一樣,用 _ 作為匿名函數的函數名,這樣,匿名函數作為參數時,形式上就是 fun(_()::[[ xxx; ]]),在閱讀時,區分度比 fun(()::[[ xxx; ]])要好一些。使用 _ 作函數名是js本身語法允許的,且在js中,這種低階的函數也確實可以命名的。比如
setTimeout(function test(){ setTimeout(test, 1000}, 1000);
所以這並沒有破壞js的規矩。
7. var 怎麼翻譯。翻譯為變量過於累贅,我找到了一個較好的詞:“元”。這個數學中常用的詞用在這裡很貼切。
在測試中文編程時,我找到了一點感覺。比如,我們有時將一些簡單的變量命名為 a, b,在中文中,如果強譯為甲乙,就顯得太文縐縐,譯為天地玄黃,那就更中世紀了。我發現使用“一、二”這樣的措辭,看上去不但符合語感,而且又蘊涵了參數的次序,編程時很實用。
如果真正進行中文編程,必然會找到很多不一樣的措辭,想來也是一塊新天地。
不過,大家都知道,中文編程的障礙除了語言本身,庫也是一件棘手的事。如果要吃掉英文的庫,我在2003年提出的表像中文的思路會更可取。