創造編程語言應該學習什麼語言?設計編程語言最好是用C/C++嗎?

現在使用javascript和python目前的水平感覺和設計編程語言還不搭邊。


啥,創造編程語言不是應該用 LaTeX 寫各種長得像這樣的東西嗎?

dfrac{Gammavdash x:A}{Gammavdash f x:B}


跟這個類似?什麼語言最適合寫編譯器/解釋器? - RednaxelaFX 的回答 - 知乎

「設計」編程語言其實不是用C/C++啥的,而是用各種「形式語言」,方便準確地定義出語言的語義。

實現編程語言才是C/C++會沾上邊的事情。但其實有很多因素會影響用什麼語言好,例如說要在怎樣的環境里運行,作者是習慣面向對象還是函數式範式,還是說作者更喜歡對其它東西依賴少的語言,等等。

用JavaScript當然也可以實現編程語言。有很多現成的例子。例如說它可以用來實現自己:

  • 用JavaScript寫JavaScript的語法分析器(解析器):Esprima、Acorn
  • 用JavaScript寫JavaScript的解釋器:Narcissus
  • 用JavaScript寫完整的編譯到機器碼的編譯器+運行時:Tachyon

它也可以用來做很多別的東西(實現別的語言),像是有不少parser generator都有JavaScript的目標,例如PEG.js、OMeta、ANTLR之類。要用它來初探編程語言的實現也未嘗不可。

可以先定一個小的目標,從Douglas Crockford的Top Down Operator Precedence開始學習。


如果說得是怎麼實現的話,當然是函數式語言最好,首推Haskell和F#,最大限度降低煩惱。


我覺得這個問題並不是一個好問題,因為問題裡面假設了很多東西(抱歉)。類似問題也是我在接觸編程時經常想的問題,現在有了一些經驗,也算回饋社會吧。但跟以前一樣,我們先來分解一下問題,然後再給答案。答案會中英夾雜;把英文辭彙翻譯成中文會阻礙很多表達。

「創造編程語言應該學習什麼語言?」

很抱歉,創造可以理解為設計新的語言,也可以理解為一種已有語言的個人實現。題主如果縮小問題範圍可以節省大家的時間。

如果樓主問的是「實現一門現有的編程語言應該用什麼語言?」這個問題簡單很多。考慮到最後需要 Bootstrapping (compilers),最終都沒有差別。如果你只是做了玩玩,選你喜歡的語言。如果你在認真的發明一門編程語言,繼續往下看吧。

發明編程語言可以分為兩[1]部分,Syntax 和 Semantics。如果你想要發明的是語言的外表,那你指的是 Syntax,發明這部分不需要學習什麼,你可以天馬行空,任意發揮。包括是用括弧還是空格來分割 token(像 lisp 還是其它語言),是用大括弧還是縮進來表示一個 Scope (對比你熟悉的 Python 和 C/C++),定義 Named function 和 Anonymous function 是否用不同的關鍵字(Python 的 def 和 lambda,對比 ES6 以前的 Javascript),定義 Type 的時候 Type 是在前面還是後面,等等。等你需要實現它,知道 Parser 怎麼工作的之後,你需要再「改進」語言的 Syntax,因為並不是所有的 Syntax 都適合 Parsing。另外一個非常有代表的例子是 Facebook 的 Reason,它重新定義了 Ocaml 的 Syntax,但沿用 Parser 後 Typed Lambda phase 之後的所有的東西。

上面說的是 Syntax,下面說 Semantics。如果你翻看美國大學編程語言理論(Programming Language Theory,下面簡稱 PLT)課的推薦教材(不是編譯理論),大部分教材都不會提及 Syntax。因為發明編程語言的核心在於設計新的或者是融合現有的 Semantics,實現一門編程語言給別人用才需要考慮到 Syntax [2]。Semantics 定義的是程序運行時候每個字和每個符號到底是什麼意思,所以如果你在設計一門語言,你應該學習的不是哪一門編程語言,而是

  1. 需要想想你的編程語言要什麼功能來解決什麼問題?(比如說 Class 繼承不夠用?用 Mixins[3])
  2. 需要藉助 PLT 用數學的形式表達你的想法(因為一不留神就會設計成 Javascript 那樣亂七八糟的語言,會有很多出乎意料的 Semantics!)

因為用哪一門編程語言都會讓你陷在編程的細節裡面浪費時間,而設計語言需要 God View!所以設計一門語言並不是以哪一門語言為開端的。

設計一門語言應該以定義 Semantics 為開端,而定義 Semantics 現在有兩個工具,一個是 operational semantics,一個是 denotational semantics。做PLT的人常常用這兩種方法來表達他們設計的語言都有哪些功能。比如這篇[3]論文裡面的 classicJava。

(其實大部分人(包括我)沒有需要設計新的編程語言的需求,所以都是找一個 Language specification,然後用代碼實現而已。也就是沒有第一步,甚至於第二步都不需要,因為 specification 已經在那了,各種 operational semantics 也沒有什麼用,如果有用,也只是用於證明這個specification很好或者是很糟糕。一般都是很糟糕:-()

我覺得現在可以回答你的問題了。

「設計編程語言最好使用C/C++嗎?」

不,設計編程語言在設計這個階段並不使用哪一門特定的語言,因為現有的語言都有亂七八糟的毛病。這就跟專業設計師設計一個新的Web UI一樣,不會直接上 HTML/CSS/JavaScript,你需要 sketch 或者是 Photoshop 這樣的東西,你需要快速,準確地先定義好框架,然後再開始。當然,設計和實現沒法搞成外包軟體那樣子的,是一個迭代的過程。

迭代的過程是怎樣的?一種方法是設計一個 Core Language,然後把其他的功能 Translate 成 Core Language,這樣可以保證設計這個語言時語言裡面只包含必要的結構,所有不必須要的東西都不放到 Core 裡面。這個 Translate 的過程會損失 Performance,但可以保證設計的精良!比如 Racket 和 Pyret 都有自己的 Core Language,比如我在學校的時候跟其他人做的 Python 的 core language [4] 和我自己寫的 SmallTalk 的 core language[5]。

因為 Core Language 非常小,semantics 非常容易寫,所以之前大家還做了 JavaScript 的 Core Language [6] (注意看這篇 blog,200 頁的 JavaScript specification 被精簡到了 3 頁!),以及我參與的 LambdaS5 [7]。

我認為還有最後一個問題沒有回答,就是在實現一門編程語言的時候,有什麼好的語言推薦(這才是題主的本意吧?)如果題主特別注重 Semantics 的表達,那我建議那些以 s-expression 為基礎的語言[8]。如果題主注重實現編程語言來開闊視野提高技能,那我建議 OCaml 或者 Haskell。如果題主注重實用性,別做這些玩具了,找個開源的語言幫他們 Fix bugs 吧。

———

[1] 其實我認為應該有三部分,除了 Syntax 和 Semantics 之外,還需要考慮到 Development Tools。如果在發明 Syntax 和 Semantics 的時候就已經把 Tools 考慮進去,這門語言會有更多相關工具的支持,想想 Golang 使用變數的大小寫來區分一個包可以導出的 symbol。

[2] 為什麼我們看到的新的語言總是跟以前的語言有一定的相似?我還在學校的時候, Pyret 發布的消息被頂到了 Hacker News 的主頁,大家評論說像這個像那個。我在辦公室對這些評論嗤之以鼻,因為我覺得大家都僅僅只是在看語言的外表而已。但 Shriram 跟我說,新的語言總是需要考慮到大家接受程度的,並且 Pyret 是給學生用,有人覺得某些 Syntax 像其他語言其實是好事情。我那個時候才意識到有這個問題存在。

[3] http://cs.brown.edu/~sk/Publications/Papers/Published/fkf-classes-mixins/paper.ps

[4] https://cs.brown.edu/~sk/Publications/Papers/Published/pmmwplck-python-full-monty/paper.pdf

[5] lijunsong / smalltalk-semantics - Bitbucket

[6] The Essence of JavaScript

[7] S5: A Semantics for Today#x27;s JavaScript

[8] 以及一本教材 Design Concepts in Programming Languages


求快的話:用Racket,建議看《Essentials of Programming Languages》。

然後你很快就能擼各種Lisp解釋器。

求穩的話:把Benjamin Pierce的書全讀一遍(順便學習OCaml或者Haskell),然後多做一點考古工作,然後試著過一遍Lambda cube,嗯我知道你馬上會走火入魔的~


創造編程語言應該學習《編程語言理論 Programming Language Theory》。

參見:Programming language theory


c和c++類似於以前的彙編語言,用於理解計算機的內存模型和函數模型,看個人興趣了。

目前必須會的語言是java,js,python


你問的是 PL(T)?各種Lisp(Scheme, Racket什麼的)。


Prolog,因為你幾乎就是在寫BNF。如果你再用CFG(Context Free Grammars)和term expansion大法,那完全就是作弊。。。


不要貿然入PLT或者類型論的坑。然後就陷入抽象代數數理邏輯範疇論的更大的坑。

從實現類似basic語言的解釋器開始。

理論入門第一本書建議《程序設計語言實踐之路》。


毫無疑問是Lisp

可以從最簡單的scheme開始


手上有一套java編譯器的代碼, 作者就是 scala的作者"從此Javac1.3開始, 都沿用馬丁的javac編譯器.這件事發生在2000年" 為什麼說 Scala 是 JVM 上的 C++? @紫杉


推薦閱讀:

函數式編程的函數是如何實現的?
為什麼沒有中文的編程?
除了 Go、Rust、Nim,還有哪些新編程語言更靠譜?
作為程序員的你是在什麼時候「突然開竅」的?
為什麼C++語法這麼複雜?

TAG:編程語言 | 編程 | 編譯原理 | 編譯器 | 編譯 |