(發散性問題,請隨意加上假設)一門編程語言同時擁有解釋器和編譯器的必要性有多大?
比如Haskell就兩個都有。解釋器必須是要能做成REPL的那種,僅僅是編譯後運行再輸出結果的不能算(可能描述有點不準確,歡迎糾正
repl和解釋器沒有必然關係,沒有解釋器照樣可以做repl。比如sbcl就把cmucl的解釋器拿掉了,因為他們感覺讓解釋器和編譯器保持語義上的一致挺麻煩,不想做(這個團隊挺萌的 ( "? " )),但sbcl的repl仍然是最牛逼的repl
現在做解釋器至少有兩個原因
01 先做解釋器,以解釋器的語義為標準來做編譯器的,比如wasm,一個解釋器對應多個編譯器
02 便於系統移植,比如ocaml,racket和java。寫解釋器(虛擬機)比寫後端要簡單。不同系統的後端代碼完全不同,但是解釋器代碼基本上可以共享
其實解釋器和編譯器之間的界限非常模糊。解釋器不過是一個運行中間代碼的虛擬機,它也可以做得非常底層,非常接近機器
我工作中就使用了OCaml同時擁有解釋器和編譯器的特點,具體就是業務相關的邏輯都丟在OCaml裡面做,調用的時候從C那邊調用OCaml的腳本,C根據OCaml返回的結果執行特定的數據修改,而OCaml這邊框架性和業務上重用性的代碼是編譯的,設計到具體對象比如具體某個地鐵的邏輯或者大鐵的邏輯的時候就是腳本的代碼搞定。這樣做就方便在,我調試的時候基本保存腳本修改就可以了,程序都可以不中斷,OCaml那邊也不需要重新編譯,加之在OCaml Merlin的檢查準確度奇高,效率提高的不是一點兩點,如果真的需要打包編譯就最後發布的時候再編譯一下。缺點就是軟體得打包上OCaml一起發布,不過還好去年他們修改了許可證,這個問題就不怎是問題了。
另外OCaml同時有解釋器,位元組碼編譯器和機器碼編譯器。。。而且這個解釋器是支持REPL的
沒有必然相關性,那麼多語言都沒有解釋器也還不是活得好好的。但是你要是覺得這個語言適合做解釋,當然可以做上去啊,因為有了解釋器,對於某些用戶是有吸引力的。比如大家學js和py的時候不就很喜歡解釋器嘛。。。但是重點還是編譯器,做好這個才是正事。因為世界上大多數人都還是要做點東西來用的,而不是一直在repl裡面玩來玩去。
除了 Haskell 還有不少語言也有題主所要表達的實現。比如 Python, Ruby, Javascript, PHP, Scala 都有 REPL,可是實現方式差得遠了。
一個簡單的例子:輸出類型,下斷點,展開數據結構啊。都是不錯的。
很多語言都是這樣的,編譯為位元組碼,然後放解釋器執行(事實上直接解釋既麻煩又沒有必要)
也可能我誤解了題主的意思
就我所了解的各種情形,Repl這種東西,用來教學演示非常方便,但除此之外益處不是非常大。
一門成熟的語言的用途很少在於交互,編譯運行往往是更加實際的需求。比如一個網站伺服器需要讓它自己穩定地跑起來,一般不需要人工的介入。世界上絕大部分工作到最後會成為定式,讓我們高效地編譯運行它們。我的理解是,有Repl的語言便於學習和推廣,變得流行。
但乾貨還是編譯器,這是正事。我不知道某些靜態語言的解釋器怎麼弄的,但是這也許是賦予了語言動態更新的能力。動態能力會方便控制程序,在良好的代碼規範(不可避免有時需要高超的技巧)下也不會增加程序管理的難度。
作為一個學東西極其不精的蒟蒻,,,解釋器最大的用處就是在自己不確定一個語法點的時候可以很簡單的打開解釋器寫一個例子試試。。。
至於是不是REPL,,,對於窩的需求並沒有影響。。。
而對於非REPL的情況,,,也許用解釋器debug編譯器的時候用起來也會很方便吧。。。
如果需要用代碼片段來測試的話,解釋器就有存在價值。如果編譯器也有存在的價值,就能共存了。
想問,解釋器執行和編譯成bytecode之類的後在虛擬機上執行有甚麼本質上的分別
推薦閱讀:
※如何快速而準確地判斷一門語言的語法(或部分語法)屬於哪個Chomsky Hierarchy?
※實現一個markdown解析器需要具備那些知識?
※如何在編程中更好地踩坑與進步?
※全局靜態變數,互斥信號量等在內存中是怎麼處理?
※shift reduce,預測分析,遞歸下降分析(這是解析方法)和LL(K) LR(K) SLR以LALR的關係?