作者: ** 張宏波**貌踏, 前OCaml編譯器核心作者十饥,現(xiàn)BuckleScript作者。
近日祖乳,Bloomberg 宣布其開源的 JavaScript 編譯器 BuckleScript 到達(dá)了1.0 版本逗堵, 作為其作者,我很高興向大家分享它的意義和功能眷昆。
誘人的JS平臺(tái)
Bloomberg 早在04年就開始在服務(wù)器端使用 JS 了蜒秤,現(xiàn)在 JS 已經(jīng)是其內(nèi)部使用最多的程序語言之一,有著豐富的大規(guī)模開發(fā)部署 JS 的經(jīng)驗(yàn)亚斋。而在開源世界作媚,隨著幾大IT巨頭對(duì) JS 引擎和工具的大力投入,以及 NodeJS 的興起帅刊,這幾年纸泡,JS已經(jīng)成為工業(yè)界炙手可熱的程序語言。
?不難發(fā)現(xiàn)現(xiàn)在的軟件行業(yè)——從互聯(lián)網(wǎng)行業(yè)到傳統(tǒng)軟件領(lǐng)域—— JS?平臺(tái)赖瞒,
這個(gè)唯一的跨平臺(tái)語言正在吞噬著越來越多的軟件領(lǐng)域(因?yàn)橐苿?dòng)的崛起Java 已經(jīng)不再是一個(gè)跨平臺(tái)語言了):
瀏覽器不再單單只是投放內(nèi)容的一個(gè)平臺(tái)女揭,越來越多的應(yīng)用程序開始通過瀏覽器直接部署,像BuckleScript playground這
樣的整個(gè)工業(yè)級(jí)別的編譯器可以流暢的直接跑在瀏覽器上栏饮,這在5年前甚至都是不可想象的田绑。Google最近主推的Progressive Web APP 將會(huì)給瀏覽器帶來更強(qiáng)大的API。而最新的Web Assembly 標(biāo)準(zhǔn) 將會(huì)使得 JavaScript 平臺(tái)可以覆蓋更多的領(lǐng)域:比如傳統(tǒng)的數(shù)值計(jì)算領(lǐng)域抡爹。WASM 相當(dāng)于給 JS 提供了一個(gè)接入原生平臺(tái)的FFI掩驱, JS 作為這個(gè)平臺(tái)的膠水語言毫無疑問有著最多的機(jī)會(huì)。
JS 平臺(tái)已經(jīng)不再局限于瀏覽器, 相反它已經(jīng)開始反噬欧穴, 開始入侵其他領(lǐng)域民逼。最有名的是服務(wù)器端NodeJS, 桌面端Electron涮帘, 物聯(lián)網(wǎng) IoT拼苍, 移動(dòng)端React Native 等。
然而 JS 作為一個(gè)只花了兩周時(shí)間開發(fā)的動(dòng)態(tài)語言是很難承載大規(guī)模调缨,高性能開發(fā)的疮鲫。它最主要的痛點(diǎn)有兩個(gè):
程序沒有類型 很難做維護(hù)和安全的重構(gòu)
程序性能過于依賴JS引擎的優(yōu)化,性能很難預(yù)測(cè)弦叶,而且因?yàn)椴煌嫘阅茏兓^大
工業(yè)界需要更快更好的JS編譯器
雖然JS平臺(tái)很誘人俊犯,但是“動(dòng)態(tài)語言難于構(gòu)建大型程序”基本上已經(jīng)是業(yè)界共識(shí),一旦程序規(guī)模上來伤哺,維護(hù)起來基本上就是噩夢(mèng)燕侠,在原來的Hack上添加新的Hack, 沒有人敢修改原來的代碼立莉。
在BuckleScript之前绢彤,業(yè)界比較成熟的具有工業(yè)強(qiáng)度的JS替代語言主要是微軟的TypeScript,那么BuckleScript相比TypeScript主要有哪些優(yōu)點(diǎn)呢?我們可以從以下幾點(diǎn)來分析:
更多的平臺(tái)拓展性
BuckleScript 不是一個(gè)新的語言蜓耻,它是把一個(gè)已經(jīng)存在將近30年的語言 OCaml 編譯成可讀的 JS 茫舶。而OCaml本身對(duì)很多平臺(tái)存在原生的后端支持。像golang一樣刹淌,OCaml可以編譯出匯編代碼到iOS奇适、Android、Windows芦鳍、Linux嚷往、MacOS。而TypeScript只有JavaScript 一個(gè)后端柠衅。
擁抱 JavaScript 并不代表我們就要拋棄原生平臺(tái)皮仁,當(dāng)我們需要更快更可靠的性能的時(shí)候,我們可以有更多的選擇菲宴。比如贷祈,做工具鏈的時(shí)候, TypeScript 的編譯器同樣也是用 TypeScript 寫得可以跑在瀏覽器里喝峦,也可以跑在node上势誊,但是它跑在node上得時(shí)候就比BuckleScript編譯成匯編跑慢不止一個(gè)數(shù)量級(jí)。更好的類型安全谣蠢,更多的類型推斷粟耻,更好的語言特性
TypeScript是一個(gè)JS的超集查近,它存在很多歷史包袱。微軟引入TypeScript更多的是作為一個(gè)工具來使用的比如IDE的代碼補(bǔ)全挤忙,相對(duì)安全的代碼重構(gòu)霜威。而這個(gè)類型的準(zhǔn)確性從第一天開始就不是它的設(shè)計(jì)初衷,以至于Facebook自己設(shè)計(jì)了一個(gè)相對(duì)更準(zhǔn)確地類型系統(tǒng) Flow册烈。 OCaml 的類型系統(tǒng)是已經(jīng)被形式化的證明過正確的戈泼。也就是說從理論上 BuckleScript 能夠保證一旦編譯通過是不會(huì)有運(yùn)行時(shí)候類型錯(cuò)誤的,而TypeScript卻做不到這點(diǎn)赏僧。
TypeScript的類型推斷很弱大猛,基本上所有參數(shù)都需要顯示的標(biāo)注類型。不光是這點(diǎn)淀零,像對(duì)函數(shù)式編程的支持挽绩,高階類型系統(tǒng)GADT的支持幾乎是沒有。而OCaml本身是一個(gè)比Elm窑滞,PureScript還要強(qiáng)大的多的語言琼牧,它自身有一個(gè)非常高階的module system恢筝,是為數(shù)不多的對(duì)dependent type提供支持的語言哀卫,polymorphic variant。而且pattern match的編譯器也是優(yōu)化過的撬槽。程序優(yōu)化此改,代碼刪除,閃電一樣的編譯速度
BuckleScript不只是一個(gè)編譯器更是一個(gè)optimizing compiler: 它做過的優(yōu)化有: Code motion,Purity analysis, Cross module inliner, Constant folding/propagation, Partial evaluation,Strength reduction, escape analysis侄柔。我們做的benchmark顯示同樣immutable data structure共啃,比如facebook immutablejs,
BuckleScript的實(shí)現(xiàn)有時(shí)候要快兩到三倍不止,生成的代碼經(jīng)過代碼刪除之后只有不到 1K字節(jié)暂题。而相比之下TypeScript編譯器并不會(huì)做任何優(yōu)化工作移剪。
由于OCaml可以編譯到匯編和JS, 而本身的BuckleScriptl編譯器也可以編譯到JS 和匯編薪者。用戶可以感受?JS版本的編譯速度纵苛,而匯編版本的編譯器更是要快一個(gè)數(shù)量級(jí) 編譯單個(gè)文件只需要十幾毫秒。
總之言津,與現(xiàn)有的其他JavaScript轉(zhuǎn)譯器比較攻人,BuckleScript 旨在提供更快的編譯速度, 更好的運(yùn)行速度悬槽,可讀和?更少的代碼輸出怀吻,以及最重要的和JS的互操作性。
BuckleScript 現(xiàn)狀以及未來 以及和Reason的整合
BuckleScript已經(jīng)被一些公司所采用初婆,并且反饋很好蓬坡,例如猿棉,下面是Facebook的程序員的評(píng)論:
I'm on the Facebook Reason team, and we're using BuckleScript to
compile OCaml into the best compiler output I've ever seen. People
didn't recognize that my React components were generated, not hand-written.
?評(píng)論中提到的Reason是由Facebook原React團(tuán)隊(duì)開發(fā)的,它是為 OCaml 提供的 JavaScript 類前端語法渣窜, 相當(dāng)于給 OCaml 換了個(gè)殼铺根,類似于 CoffeScript 對(duì)于 JS。
要強(qiáng)調(diào)的是乔宿, Reason 團(tuán)隊(duì)不僅僅在改進(jìn)OCaml的語法位迂,同時(shí)也在努力改善OCaml中的工具鏈,像構(gòu)建系統(tǒng)详瑞、IDE等掂林。我們之間有非常緊密的合作關(guān)系,BuckleScript外部函數(shù)接口的設(shè)計(jì)以及和JS的互操作得到了Reason團(tuán)隊(duì)很多反饋坝橡,希望將來能推出下一個(gè)版本的UI框架泻帮,這樣有可能React Native 有可能真的跑在原生的后端上(OCaml 能在iOS平臺(tái)編譯出原生的匯編)。
BuckleScript未來的發(fā)展计寇,我們制定了以下路線:
- BuckleScript把OCaml編譯成JavaScript锣杂。所以,我們會(huì)跟進(jìn)OCaml的最新發(fā)展番宁,并升級(jí)到最新版本的編譯器元莫。最近OCaml中有很多令人興奮的新特性,我們會(huì)從中受益蝶押。例如踱蠢,Flambda的優(yōu)化將會(huì)使我們的編譯器更快。
- 我們將與其他的團(tuán)隊(duì)(Bloomberg內(nèi)部的或外部的)合作棋电,為BuckleScript提供更多的綁定(NodeJS茎截、Electron和React)。
- BuckleScript的編譯器也被編譯成JavaScript赶盔,這意味著用戶不僅可以在任意地方運(yùn)行OCaml/Reason企锌,同時(shí)也可以在任意地方寫OCaml/Reason。我們將所有的東西都打包成一個(gè)JavaScript文件于未,用戶可以快速上手不會(huì)遭遇JavaScript疲勞撕攒。同時(shí),我們也將提高我們的playground沉眶,使之成為更好的Web IDE打却。