CMU本科生開(kāi)源文言文編程語(yǔ)言,數(shù)天2K星
「昔者蒼頡作書(shū),而天雨粟,鬼夜哭」,漢字的出現(xiàn),誕生了世界上一個(gè)偉大的文明。而編程語(yǔ)言的出現(xiàn),讓人類和計(jì)算機(jī)產(chǎn)生了真正的聯(lián)系,推動(dòng)了現(xiàn)代文明的發(fā)展。
那么,將古代漢語(yǔ)和編程語(yǔ)言結(jié)合又會(huì)產(chǎn)生怎樣的火花?最近,GitHub 上出現(xiàn)了一個(gè)文言文做代碼的項(xiàng)目,幾乎是世界上第一門(mén)文言文編程語(yǔ)言(當(dāng)然,底層還是轉(zhuǎn)換成 Python 或 JavaScript 運(yùn)行)。
如果中文是編程語(yǔ)言中使用的主要語(yǔ)言,我們中國(guó)人學(xué)習(xí)編程是否會(huì)更簡(jiǎn)單?
這是知乎上討論非常火熱的話題。很多接觸過(guò)編程的人都知道「易語(yǔ)言」,這是一種使用中文代替編程語(yǔ)言中的英文的編程語(yǔ)言,同樣可以實(shí)現(xiàn)程序功能。近日,一位卡內(nèi)基梅隆大學(xué)(CMU)的大四學(xué)生開(kāi)發(fā)了基于文言文的編程語(yǔ)言,高中語(yǔ)文三大怕的文言文終于找上程序員了。
項(xiàng)目地址:https://github.com/LingDong-/wenyan-lang
這一項(xiàng)目并不是簡(jiǎn)單的將程序中的英文字符換成了中文,而是利用 NLP 的一些技術(shù),將文言文程序語(yǔ)法轉(zhuǎn)換到 JavaScript 或 Python 運(yùn)行,有一定的技術(shù)難度。項(xiàng)目問(wèn)世幾日即獲贊 2.2K,還得到了很多人的微博轉(zhuǎn)發(fā)。
作為橫跨媒體和 AI 的機(jī)器之心也測(cè)試了這一項(xiàng)目,項(xiàng)目作者的腦洞、文采和創(chuàng)意著實(shí)令人驚訝。
如果讀者想快速試一試,你也可以玩一玩在線 IDE,上面有很多預(yù)定義的函數(shù)。即使在手機(jī)上,我們也能編輯并運(yùn)行「文言文代碼」。
在線地址:http://wenyan-lang.lingdong.works/ide.html
作者在項(xiàng)目開(kāi)篇使用了一段文言文,介紹了建立這個(gè)項(xiàng)目的初衷。
翻譯如下:
在堯舜時(shí)代,人們使用結(jié)繩和數(shù)手指來(lái)計(jì)算。當(dāng)時(shí)怎么能夠預(yù)料到,幾百代人之后計(jì)算機(jī)的巧妙呢!計(jì)算機(jī)比魯班(公輸盤(pán))的木鳶更加精巧,比諸葛亮(武侯)的木牛流馬更好。此外,編程語(yǔ)言數(shù)量眾多,如同《天官書(shū)》記錄的星宿一般多,又比《山海經(jīng)》中記錄的飛禽走獸還要奇特。Go(鼠)、Rust(蟹)、Ruby(鑽)、Fishshell(魚(yú))因速度而出名。Python(蛇)、Php(象)、Perl(駱)和 JavaScript(犀)則各有獨(dú)特之處。我這才理解到,為什么鬼會(huì)夜哭,天上會(huì)下粟雨。
(注:傳倉(cāng)頡造字后,鬼神啼哭,天降粟雨)
但以往從未有人使用過(guò)文言文進(jìn)行編程。這并不是傳承文脈、保護(hù)文心的好方法,所以我才產(chǎn)生了用文言文編程的想法。我目前還太年輕,讀過(guò)的書(shū)也沒(méi)有破萬(wàn)卷。如今身處遙遠(yuǎn)的國(guó)家(美國(guó)),也很久沒(méi)有接觸中文了。但是我一直對(duì)文學(xué)很有興趣,編寫(xiě)的程序有時(shí)候也得到人們的一些肯定。正如王希孟和莊子一般,并不因?yàn)槟贻p或者知識(shí)的浩瀚無(wú)涯而退縮,于是寫(xiě)下了這些話。
(注:王希孟,北宋畫(huà)家,18歲畫(huà)成傳世名作《千里江山圖》)
我既沒(méi)有像李賀那樣嘔心瀝血,也沒(méi)有像李商隱那樣口角流沫(形容讀書(shū)勤奮)。項(xiàng)目完成后,我將繼續(xù)以干將鑄劍的精神勉勵(lì)自己,帶著越王臥薪嘗膽的精神繼續(xù)向前。我自己雖想效仿《算經(jīng)十書(shū)》的筆法,只是遺憾沒(méi)有唐宋八大家那樣淋漓的文筆。正如庾信在《哀江南賦》所寫(xiě):「陸機(jī)聽(tīng)了心甘情愿地拍掌;張衡見(jiàn)了將輕視它也是理所當(dāng)然」(意指如果被人嘲笑,也是理所當(dāng)然,我不會(huì)太過(guò)介意)。
盡管這項(xiàng)目只有覆甕的價(jià)值(一點(diǎn)微小的工作),但是還有完善的空間。雖然沒(méi)有像呂不韋那樣有一字千金的本錢(qián),但是我對(duì)交流的渴望是一樣的。
這也正是開(kāi)源的精神內(nèi)核,我們以此互相勉勵(lì)吧。
作者是誰(shuí)?
Lingdong Huang 目前是 CMU 計(jì)算機(jī)專業(yè)大四學(xué)生,明年就本科畢業(yè)了。我們可以看到他曾在迪士尼研究實(shí)驗(yàn)室、紐約時(shí)報(bào)等大廠實(shí)習(xí)過(guò)。而且從個(gè)人網(wǎng)站中,很明顯可以發(fā)現(xiàn)他高中就開(kāi)始做各種小項(xiàng)目,包括視覺(jué)和自然語(yǔ)言的都有。
寫(xiě)得了代碼、讀得了文言文,文化底蘊(yùn)還這么強(qiáng),現(xiàn)在的本科生已經(jīng)這么厲害了。
個(gè)人網(wǎng)站:https://lingdong.works
文言文編程是什么情況
用文言文編程是什么樣一種體驗(yàn)?是不是既能學(xué)習(xí)文言文,又能搞定編程邏輯?介紹不如演示,我們先看看編程世界里的第一段代碼,廣大程序員學(xué)習(xí)的第一句「HelloWord」是什么樣的。如果讀者們文言文比較溜,或者了解一點(diǎn)程序思維,那么可以了解,下面一段文言文代碼就是輸出三遍「問(wèn)天地好在」,也就是「HelloWord」的文言文版。
- 吾有一數(shù)。曰三。名之曰「甲」。
- 為是「甲」遍。
- 吾有一言。曰「「問(wèn)天地好在。」」。書(shū)之。
- 云云。
具體而言,先定義一個(gè)數(shù)「3」,并命名為「甲」,現(xiàn)在循環(huán)「甲」次,每次在屏幕上打印出「問(wèn)天地好在。」。作者會(huì)將其翻譯成對(duì)應(yīng)的 Javascript 代碼,從而幫助我們理解。
- var n = 3;
- for (var i = 0; i < n; i++) {
- console.log("問(wèn)天地好在");
- }
當(dāng)然,按照我們的習(xí)慣,改寫(xiě)成 Python 代碼也是沒(méi)問(wèn)題的:
- a = 3
- for i in range(a):
- print("問(wèn)天地好在")
為了更貼近文言文的表達(dá)習(xí)慣,Lingdong Huang 在項(xiàng)目表示各種標(biāo)點(diǎn)和換行都是可以去掉的,上面的文言文代碼可以等價(jià)寫(xiě)為:
- 吾有一數(shù)曰三名之曰「甲」為是「甲」遍吾有一言曰「「問(wèn)天地好在」」書(shū)之云云
突然感覺(jué),好像沒(méi)了符號(hào)的文言文代碼更容易懂了?
這樣看起來(lái)似乎很簡(jiǎn)單?那你就小瞧了文言文編程的魅力。比如說(shuō)程序員入門(mén)必修課「斐波那契數(shù)列」,每一項(xiàng)都是前兩項(xiàng)的和,第一項(xiàng)是 0、第二項(xiàng)是 0+1、第三項(xiàng)是 1+1 等等。
如果用文言文來(lái)寫(xiě)斐波那契數(shù)列,我們需要建立一個(gè)函數(shù),函數(shù)的輸入是斐波那契項(xiàng)數(shù),輸出是該項(xiàng)具體的值。如果用文言文來(lái)寫(xiě),畫(huà)風(fēng)是這樣的:
最后一句「施「斐氏列」於七。書(shū)之。」是調(diào)用函數(shù),并輸出第 7 個(gè)結(jié)果。雖然看上去比較麻煩,但我們還是可以細(xì)細(xì)閱讀,例如「吾有一術(shù)。名之曰「斐氏列」。」很明顯定義了一個(gè)函數(shù),函數(shù)名是「斐氏列」;「若「因」等於零者。昔之「果」者。今「因」是矣云云。」表示如果「因」這個(gè)變量等于 0,那么就將「因」這個(gè)變量的值賦值到「果」變量。
如果閱讀上還有困難,那么也可以看看項(xiàng)目作者提供的對(duì)應(yīng) Javascript 代碼。不過(guò)我們可以嘗試把它翻譯成 Python 語(yǔ)言,翻譯結(jié)果如下所示:
- def fei_seq(yin):
- tou = 0
- wei = 1
- ji = 1
- guo = 0
- if yin == 0:
- guo = yin
- if yin == 1:
- guo = yin
- while True:
- if ji >= yin:
- break
- ans_ = tou +wei
- guo = ans_
- tou = wei
- wei = guo
- ans_ = ji + 1
- ji = ans_
- return guo
- print(fei_seq(7))
當(dāng)然,Python 作為一種極其精簡(jiǎn)的語(yǔ)言,真正用它來(lái)寫(xiě)斐波那契數(shù)列肯定代碼量要少很多。不過(guò),借助這段翻譯,理解文言文編程還是要簡(jiǎn)單很多的。如果讀者想要試一試,可以復(fù)制這個(gè) GitHub 項(xiàng)目,并在本地編譯,也可以直接使用在線 IDE 編譯你的代碼。
下面,作為一種「新語(yǔ)言」,我們當(dāng)然要了解它的神奇語(yǔ)法,不論是定義變量、函數(shù),還是生成數(shù)列,文言文都有對(duì)應(yīng)的語(yǔ)法。
語(yǔ)法規(guī)則
考慮到文言文和其他編程語(yǔ)言的轉(zhuǎn)換有一定的理解難度,作者提供了一些語(yǔ)法轉(zhuǎn)換規(guī)則表,供參考。
變量命名
條件/循環(huán)
數(shù)學(xué)計(jì)算
數(shù)組(列表)
這里從「1」開(kāi)始計(jì)數(shù)。
函數(shù)
讓你的代碼更有逼格
看厭了黑底的代碼?項(xiàng)目還提供了一個(gè)炫酷的「古文代碼生成器」,我們可以把自己的文言文代碼轉(zhuǎn)換成古書(shū)中從右到左,從上到下,沒(méi)有標(biāo)點(diǎn)的古文。是不是更有 B 格了?這個(gè)生成器還有 SVG 文件,可以將代碼再提取出來(lái),重新運(yùn)行。
以下為項(xiàng)目作者嘗試的「圖靈機(jī)」代碼: