些人會(huì)說語言學(xué)到最后不都差不多嗎?其實(shí)可以這樣講,也可以不這樣講。雖然每種語言的表達(dá)能力大部分是重合的,只是語法表現(xiàn)形式不一樣,但是由于歷史發(fā)展的原因,每種語言形成了自己的支撐環(huán)境,所以都有其主要的適用范圍。
C、C++、Python和Java四種是通用編程語言,JavaScript和PHP算是Web環(huán)境的專用編程語言。
由于其底層操作特性和歷史的積累,在嵌入式領(lǐng)域是當(dāng)之無愧的王者。
是一種支持最廣泛編程范式的復(fù)雜語言,在高級語言當(dāng)中,處理運(yùn)行速度是最快的,大部分的游戲軟件,系統(tǒng)都是由C++來編寫的。
作為一種靈活的輕便的通用型腳本語言,使用范圍比較廣,從應(yīng)用軟件到Web開發(fā)都有它的身影,由于其解釋語言的特點(diǎn),比較適合輕量級或原型開發(fā);
Java由于其跨平臺(tái)可移植性,在Web開發(fā)領(lǐng)域大放異彩,特別是在企業(yè)級Web開發(fā),同時(shí)由于Android系統(tǒng)采用Java來開發(fā)應(yīng)用程序,所以也隨著Android的發(fā)展而應(yīng)用越發(fā)廣泛;
JavaScript語言由于其是瀏覽器內(nèi)置的腳本語言,是Web前端開發(fā)的主流,近年來由于google的V8引擎開源,出現(xiàn)了Node.js之類JavaScript后臺(tái)開發(fā)框架,把JavaScript的應(yīng)用領(lǐng)域擴(kuò)展到了Web后臺(tái)。
獨(dú)特的語法混合了C、Java、Perl以及PHP自創(chuàng)的語法。它可以比CGI或者Perl更快速地執(zhí)行動(dòng)態(tài)網(wǎng)頁;還可以執(zhí)行編譯后代碼,編譯可以達(dá)到加密和優(yōu)化代碼運(yùn)行,使代碼運(yùn)行更快。
理清不同語言間主要語法特性的差異,才能更好的在合適的領(lǐng)域或場景下去應(yīng)用合適的編程語言,以滿足我們所面對的需求。這六種語言都是從C語言發(fā)展而來,所以它們的語法都比較像C語言,下面我就主要語法特性對各個(gè)語言做一個(gè)對比。
1、常量定義
C:#define TEST 0
C++:#define TEST 0
或者
const test = 0;
Python:test = 0
C#:不支持
PHP:define('test', 1);
Java:final int test = 0;
分析:JavaScript不支持常量,C、C++都用特有的預(yù)定義宏,PHP用特殊的define語法,其它的都用定義不變變量的方式。
2、變量定義
C:int test = 0;
C++:int test = 0;
Python:test = 0
JavaScript:val test = 0;
PHP:$test = 0;
Java:int test = 0;
分析:這個(gè)最基本的都支持了。
3、函數(shù)定義
C:int test(int param){}
C++:int test(int param){}
Python:def test(param):
JavaScript:function test(param){}
PHP:function test($param){}
Java:public class test{
public int test(int param){} }
分析:這個(gè)也是最基本的了,只是Java比較特殊,不支持定義類之外的函數(shù)。
4、類定義(含繼承)
C:不支持
C++:class test2: public test1{}
Python:class test2(test1):
JavaScript:function test2(){}
test2.prototype =inherit(test1.prototype){}
PHP:class test2 extend test1{}
Java:class test2 extends test1{}
分析:C由于是傳統(tǒng)面向過程的語言不支持類,其他的都支持了,只是JavaScript的類模型比較特殊,把函數(shù)作為類來使用。
5、對象定義
C:不支持
C++:test2 obj = new test2();
Python:obj = test2()
JavaScript:var obj = new test2();
PHP:$obj = new test2();
Java:test2 obj = new test2();
分析:除了C外其它語言都是通過new一個(gè)對象。
6、數(shù)組定義
C:int a[] = {1, 2, 3};
C++:int a[] = {1, 2, 3};
Python:a = [1, 2, 3]
JavaScript:var a = [1, 2, 3];
PHP:$a = array("1", "2", "3");
Java:int a[] = {1, 2, 3};
分析:數(shù)組是語言的基本特性,都支持了,只是PHP通過類似函數(shù)調(diào)用的語法來完成。
7、條件語句
C:if (test > 0){}
else if (test < 0){}
else{}
C++:if (test > 0){}
else if (test < 0){}
else{}
Python:if test > 0:
elif test < 0:
else:
JavaScript:if (test > 0){}
else if (test < 0){}
else{}
PHP:if ($test > 0){}
elseif ($test < 0){}
else{}
Java:if (test > 0){}
else if (test < 0){}
else{}
分析:這是最基本的語句,都支持了。
8、循環(huán)語句
C:for (idx=0; idx<num; idx++){}
C++:for (idx=0; idx<num; idx++){}
Python:for idx in range(1,10):
JavaScript:for (var idx=0; idx<num; idx++){}
PHP:for ($idx=0; $idx<$num; $idx++){}
Java:for (idx=0; idx<num; idx++){}
分析:這個(gè)也是基本的語句,都支持了。
9、foreach語句
C:不支持
C++:不支持
Python:for i in a:
或者
for key in d:
d[key]
JavaScript:for(i in a){}
PHP:foreach($a as $i){}
Java:for(int i : a){}
分析:foreach算是循環(huán)語句的一個(gè)變種,在操作順序容器的時(shí)候非常有用,可以看到C和C++不支持,其它的都語言內(nèi)置支持了。
10、打印語句
C:printf("test: %d", val);
C++:cout<<"test: "<<val<<endl;
Python:print "test: "+val
JavaScript:不支持
PHP:echo "test: $val";
Java:System.out.println("test :"+val);
分析:打印算是語言所運(yùn)行環(huán)境的支持庫功能,除了JavaScript外都支持了,因?yàn)镴avaScript主要使用來操控DOM樹的,沒有自己的輸出窗口所以也沒必要支持。
11、字符串定義
C:char test[] = {"helloworld"};
C++:String test = "helloworld";
Python:test = "helloworld"
JavaScript:var test = "helloworld";
PHP:$test = "helloworld";
Java:String test = "helloworld";
分析:這個(gè)都支持了,其中C++、Java都是用標(biāo)準(zhǔn)庫來現(xiàn)實(shí)的。
12、字符串串接
C:test = strcat(test1, test2);
C++:test = test1 + test2;(STL庫)
Python:test = test1 + test2
JavaScript:var test = test1 + test2;
PHP:$test = $test1 .= $test2;
Java:test = test1 + test2;
分析:很有用的功能,除了C是用標(biāo)準(zhǔn)庫函數(shù)來實(shí)現(xiàn),其它都是語言內(nèi)置支持了。
13、字符串分割
C:不支持
C++:test.substr(3, 8);
Python:test[3:8]
JavaScript:test.slice(3, 5);
PHP:substr($test, 3, 5);
Java:test.substring(3, 8);
分析:常用的功能,C不支持,Python是語言內(nèi)置支持,其他的都依靠庫來完成。
14、字符串正則表達(dá)式
C:不支持
C++:不支持
Python:test.replace("test1", "test2")
JavaScript:test.replace(/test1/gi, "test2");
PHP:str_replace($test, "test1", "test2");
Java:test.replaceAll("test1", "test2");
分析:常用的功能,可惜C、C++不支持,其他都有標(biāo)準(zhǔn)庫來支持。
15、內(nèi)置容器類型
C:數(shù)組
C++:數(shù)組
順序容器 Vector
關(guān)聯(lián)容器 Pair MapSet
Python:列表/元組
字典
JavaScript:數(shù)組
對象
PHP:數(shù)組(含關(guān)聯(lián)數(shù)組)
Java:數(shù)組
序列 Collection
映射表 Map
分析:C最簡單只支持?jǐn)?shù)組,其他都支持容器,不過主要還是順序容器和關(guān)聯(lián)容器兩大類。
16、注釋方式
C:/* */
C++://
Python:#
JavaScript:/* */
//
PHP:/* */
//
#
Java:/* */
//
分析:大概就/**/、//、#三種方式,各自支持情況不一。
17、多線程支持
C:支持
C++:支持
Python:支持
JavaScript:不支持
PHP:不支持
Java:支持
分析:四種通用編程語言都支持了,兩種專用編程語言都不支持。
18、socket支持
C:支持
C++:支持
Python:支持
JavaScript:不支持
PHP:支持
Java:支持
分析:除了JavaScript以外都支持,這也是JavaScript的應(yīng)用領(lǐng)域限制所決定的。
19、垃圾回收機(jī)制
C:不支持
C++:不支持
Python:支持
JavaScript:支持
PHP:支持
Java:支持
分析:這是現(xiàn)代語言的重要機(jī)制,C和C++不支持,其他的都支持了。
20、引入其他文件中的函數(shù)
C:export int test();
C++:export int test();
Python:from test import *
JavaScript:<script language='javascript' src="test.js"charset="utf-8"></script>
PHP:require_once('test.php');
或者
include_once('test.php');
Java:import java.util.test.*;
分析:都支持,C和C++用export,Python和Java用import,JavaScript依靠HTML腳本,PHP用自己的函數(shù)調(diào)用。
21、將字符串作為指令執(zhí)行
C:不支持
C++:不支持
Python:eval("port=5060")
JavaScript:eval("port=5060;");
PHP:eval("port=5060;");
Java:Porcess proc = new ProcessBuilder(“test”).start();
分析:很有用的一個(gè)動(dòng)態(tài)語言特性,C和C++都不支持,Java要類庫來支持,其它的語言內(nèi)置eval關(guān)鍵字.
C/C++資料分享:
需要的小伙伴們可以【點(diǎn)擊下方】鏈接哦~
近日,來自多倫多大學(xué)和 YScope 公司(為軟件系統(tǒng)提供創(chuàng)新的日志管理和故障排除工具。由一群計(jì)算機(jī)工程教授和博士創(chuàng)立)的 David Lion、多倫多大學(xué) Adrian Chiu 和 Michael Stumm、多倫多大學(xué)和 YScope 公司 Ding Yuan 共同發(fā)布了一份《調(diào)查托管語言的運(yùn)行時(shí)性能:為什么 JavaScript 和 Python 比 C++ 慢了 8 倍和 29 倍,而 Java 和 Go 卻能更快》(https://www.usenix.org/system/files/atc22-lion.pdf)的論文分析報(bào)告,深度剖析了不同編程語言運(yùn)行時(shí)在代碼開發(fā)中真實(shí)的性能情況,由此方便開發(fā)者可以精確地測量執(zhí)行任何字節(jié)碼指令所花費(fèi)的時(shí)間等。
性能是系統(tǒng)軟件不得不面對的挑戰(zhàn)
在報(bào)告中,研究人員指出,自 2015 年以來,具有集成運(yùn)行時(shí)環(huán)境的編程語言越來越受歡迎,其中,全球知名的代碼托管平臺(tái) GitHub 上最受歡迎的三種語言分別是 JavaScript、Java 和 Python。
作為開發(fā)利器,編程語言幫助開發(fā)者快速構(gòu)建各種應(yīng)用程序和服務(wù),也極大地提高了生產(chǎn)力。同時(shí),這些語言自身也提供了各種功能,如動(dòng)態(tài)類型檢查、帶有垃圾收集的內(nèi)存管理,以及動(dòng)態(tài)內(nèi)存安全檢查等等。為此,研究人員用「托管語言」(managed languages)專業(yè)術(shù)語來指代這些類型的編程語言。
現(xiàn)實(shí)來看,托管語言越來越多地被用于實(shí)現(xiàn)性能至關(guān)重要的系統(tǒng)軟件上,如Hadoop 和 Spark 都在 Java 虛擬機(jī)(JVM)上運(yùn)行,因?yàn)樗鼈兎謩e用 Java 和 Scala 實(shí)現(xiàn);Kubernetes、etcd(分布式鍵值存儲(chǔ))和 M3(由 Uber 建立的分布式時(shí)間序列數(shù)據(jù)庫和查詢引擎)都是用 Go 實(shí)現(xiàn)的。
當(dāng)前,甚至連操作系統(tǒng)(OS)的內(nèi)核 Biscuit 也是用 Go 實(shí)現(xiàn)的 。Openstack、Paypal、Instagram 和 Dropbox 都大量使用 Python,其中,Python 是 Dropbox "在后臺(tái)服務(wù)和桌面客戶端應(yīng)用中使用最廣泛的語言",在一個(gè)存儲(chǔ)庫中就有近 400 萬行 Python 代碼;JavaScript 也被用于 Facebook 的 Bladerunner pub/sub 系統(tǒng)的性能關(guān)鍵路徑中。
在開發(fā)過程中,編程語言的性能在一開始很少會(huì)被考慮到項(xiàng)目中,部分原因是不少開發(fā)者認(rèn)為性能問題可以在以后慢慢去解決,也許可以通過簡單地增加硬件來進(jìn)行橫向擴(kuò)展。
不過,隨著代碼產(chǎn)品或服務(wù)使用規(guī)模的擴(kuò)大,服務(wù)變得越來越慢或者硬件成本變高,性能成為一個(gè)不容忽視的問題。這也是為什么 Stream 要放棄了 Python 而改用 Go、 Discord 從 Go 切換到 Rust、Twitter 從 Ruby on Rails 切換到 Scala 和 Java 的主要原因。
不少開發(fā)者往往為了提升性能,想破腦袋,但現(xiàn)實(shí)只有兩條路,一條是從現(xiàn)有的代碼中想盡辦法盡可能地做優(yōu)化,另一條是思考使用的編程語言是否已經(jīng)達(dá)到了性能極限,看看有沒有必要將舊的代碼移植到一個(gè)新的性能更高的語言上。
為了徹底解開系統(tǒng)軟件中不同編程語言導(dǎo)致的性能問題,研究人員決定以 C++ 為極限,對 Java、Go、JavaScript 和 Python 四種編程,還有應(yīng)用最廣泛的運(yùn)行時(shí)系統(tǒng) CPython、OpenJDK。Node.js 與 JavaScript 的 V8 引擎進(jìn)行深入的定量性能分析。
同時(shí),研究人員還從頭開始建立了 6 個(gè)應(yīng)用程序,并創(chuàng)建了一個(gè)名為
者 | Nicholas Yang
譯者 | 核子可樂
策劃 | 褚杏娟
假如大家正在編寫前端代碼,那么會(huì)選擇哪種編程語言?目前來看,最有希望的選手主要有三個(gè):首先是最常規(guī)的 JavaScript,然后是能編譯為 WebAssembly(Wasm)的語言,最后則是能編譯成 JavaScript 的語言。
常規(guī) JavaScript 需要的配套工具最少,但代價(jià)是調(diào)試起來相當(dāng)麻煩,代碼可讀性也差。雖然選擇 JS 確實(shí)門檻較低,不過除了一味癡迷“極簡主義”的鐵粉以外,我個(gè)人覺得這個(gè)選項(xiàng)只能說一般。
能編譯為 Wasm 的語言雖然越來越多,但總體上還是新生事物。這些語言往往帶有大量的二進(jìn)制文件,因?yàn)槠渲写蠖嘈枰浜项~外的運(yùn)行時(shí)。Interop 距離發(fā)展成熟還差得遠(yuǎn)。另外,即使兩種語言都能編譯成 Wasm,也不代表它們之間就能良好實(shí)現(xiàn)互操作。再有,這個(gè)陣營的生態(tài)儲(chǔ)備還遠(yuǎn)遠(yuǎn)比不上積累了幾十年的 JavaScript DOM 庫。在 Wasm 這邊,React 和 Svelte 應(yīng)該是最好的選項(xiàng)了。大家千萬別誤會(huì),我可不是在唱衰 Wasm。它已經(jīng)擁有專屬于自己的表現(xiàn)舞臺(tái),如果大家想要在瀏覽器中運(yùn)行高計(jì)算量原生代碼,但 Wasm 就是最完美的選項(xiàng)。可如果不是這種情況,我個(gè)人不太推薦用它進(jìn)行日常前端開發(fā)。
最后剩下的就是能編譯成 JavaScript 的語言了。但這個(gè)陣營形成了一家獨(dú)大的局面,其中的老大我們稍后會(huì)具體討論。相比之下,ClojureScript、Elm、ReScript、Dart 等語言都形成了頗具體量的社區(qū),但未來市場份額還能不能進(jìn)一步擴(kuò)大尚未可知。這就很尷尬了,畢竟能編譯成 JavaScript 的語言代表的基本就是瀏覽器上的最佳編程體驗(yàn)。在它們的支持下,我們既能享受 JS 所不具備的良好功能,比如靜態(tài)類型、強(qiáng)類型、不變性、宏等,同時(shí)也能通過 bindings 支持 JS 及其廣泛的生態(tài)系統(tǒng)。而且,它們還不需要笨拙的大型運(yùn)行時(shí)。
由于 Wasm 的存在,我懷疑 JS 編譯陣營會(huì)有所保留,畢竟很多人覺得前者才是瀏覽器上的最佳編譯目標(biāo)。我其實(shí)并不同意這種觀點(diǎn),能編譯成 JavaScript 的語言還是越多越好。總之,我想借這篇文章跟大家聊聊現(xiàn)有及未來可能出現(xiàn)的前端語言,應(yīng)該朝著哪個(gè)方向發(fā)展。
這就是我前文提到的 JS 編譯陣營中的“老大”——TypeScript。TypeScript 是種很棒的語言,顯著改善了開發(fā)者體驗(yàn)。它還新增了安全層,促進(jìn)工具質(zhì)量提升,并大大降低了使用門檻。考慮到生態(tài)系統(tǒng)的繁榮現(xiàn)狀以及對 JS 類型檢查難題的妥善解決,TypeScript 確實(shí)取得了非凡的成就。
當(dāng)然,也有不少針對 TypeScript 的非議值得關(guān)注。首先就是這門語言的性能和健全性問題。需要注意的是,TypeScript 團(tuán)隊(duì)其實(shí)很清楚這兩大頑疾,而其根源是開發(fā)團(tuán)隊(duì)在項(xiàng)目之初做出的明確權(quán)衡。在我看來,這些權(quán)衡是當(dāng)時(shí)為了提高執(zhí)行效率而做出的正確選擇。
話雖如此,但性能確實(shí)是 TypeScript 最受詬病的問題。TypeScript 是自實(shí)現(xiàn)的,而且這種實(shí)現(xiàn)非常復(fù)雜。它的類型系統(tǒng)本身可以算是種迷你編程語言,這導(dǎo)致類型檢查的速度極其緩慢。
第二個(gè)問題就是健全性。這事的討論熱度沒那么高,但在編程愛好者群體內(nèi)部還挺受關(guān)注。概括來講,TypeScript 一身都是“缺陷”——allwJs 配置選項(xiàng)、any 類型和 intersection 類型,其類型系統(tǒng)根本無法保證代碼的類型安全。換言之,我們編寫的 TypeScript 很可能會(huì)觸發(fā)運(yùn)行時(shí) bug。另外,除了極其簡單的場景之外,TypeScript 還缺乏可靠的類型推斷,所以開發(fā)者在很多地方都得明確標(biāo)出類型注釋。
但同樣的,這兩點(diǎn)也是項(xiàng)目權(quán)衡的結(jié)果。
引導(dǎo)編譯器的存在對于 TypeScript 的內(nèi)部測試至關(guān)重要,這能幫助項(xiàng)目開發(fā)者理解 TypeScript 這種語言用起來的真實(shí)感受。具體來講,項(xiàng)目團(tuán)隊(duì)要體驗(yàn)如何編寫大型 JS 代碼庫,再逐步采用代碼庫中的類型。在健全性方面放松一點(diǎn),開發(fā)者才能在現(xiàn)有 JS 代碼庫中逐步引入 TypeScript,也能輕松使用 any 類型來直接擺脫類型系統(tǒng)的束縛。
光是這部分就夠單獨(dú)寫篇文章了。在我看來,TypeScript 可能是第一種更多關(guān)注開發(fā)者體驗(yàn)、而非自身語義的編程語言。它并沒有添加任何運(yùn)行時(shí)結(jié)構(gòu)、不插手性能,而是添加了一套類型系統(tǒng),并讓整個(gè)語言社區(qū)接納了這種不用類型也行、沒高質(zhì)量工具也行,還不強(qiáng)調(diào)正確性的生態(tài)氛圍。這簡直是個(gè)不可思議的壯舉。
所有這一切都表明,TypeScript 早在十年前就做出了一眾對自身產(chǎn)生巨大影響的權(quán)衡。而隨著時(shí)間推移,我覺得是時(shí)候通過新語言再做一輪權(quán)衡了。確切來講,我們需要一種具備健全性、類型推斷和更快編譯速度的語言。
要求明確了,但我們該拿什么來換?
先從健全性說起。下一代語言不再努力對各種 JS 模式進(jìn)行類型檢查,而是以獨(dú)立語言的形態(tài)通過更簡單的類型系統(tǒng)將代碼編譯成 JS。它會(huì)將現(xiàn)有 JS 代碼視頻外部互操作對象,對 JS 代碼執(zhí)行顯式運(yùn)行時(shí)類型檢查,而且依靠不同的原生語言來實(shí)現(xiàn)。
為什么要這樣?首先,我個(gè)人特別喜歡具備既健全、又相對簡單的類型系統(tǒng)的語言。我希望這種語言能夠在瀏覽器中運(yùn)行良好,而且能順暢適配現(xiàn)有 Web 生態(tài)系統(tǒng)。那些能編譯成 Wasm 的語言經(jīng)常忽略 Web 生態(tài)系統(tǒng)中的其余部分,總想在瀏覽器中建立起基于像素的原生 UI。我覺得這個(gè)想法不錯(cuò),只是跟我的觀念相悖。我只想用下一代語言開發(fā)常規(guī)網(wǎng)站;我不想要純函數(shù)式語言,而更傾向于跟 C 的老派風(fēng)格相似的語言(對不起了,Elm!);我希望這種語言能體現(xiàn)出我在工具設(shè)計(jì)上的想法。
那為什么下一代前端語言應(yīng)該誕生在現(xiàn)在這個(gè)時(shí)間點(diǎn)?俗話說得好,種一棵樹最好的時(shí)機(jī)是十年前,其次是現(xiàn)在。這十年來,JS 社區(qū)已經(jīng)發(fā)生了很大變化。人們開始學(xué)習(xí) TypeScript,也習(xí)慣于關(guān)注編譯器并通過類型進(jìn)行數(shù)據(jù)建模。現(xiàn)在,很多開發(fā)者開始使用 Rust、Swift 和 Kotlin 等語言,也意識(shí)到高質(zhì)量工具的重要性。我不是說十年前的人們會(huì)抵抗強(qiáng)調(diào)類型安全的語言,但那時(shí)候的普及難度確實(shí)更高。
明確表達(dá)了需求,有些朋友可能覺得這說的不就是 ReScript/ReasonML 嗎?沒錯(cuò),確實(shí)有幾分相像。但在理想情況下,我期待的下一代語言應(yīng)該能對 JS 代碼和特性進(jìn)行顯式運(yùn)行時(shí)類型檢查。運(yùn)行時(shí)類型檢查是達(dá)成良好互操作性的前提,這樣我們就能更輕松地隨意使用 JS 庫。
同樣地,我覺得 traits 對用戶來說也很重要,它們可以跟其他語言特性映射起來,比如 Java 接口和 C++ 概念。這可太方便了,比如輕松通過 Display trait 輸出任意類型。這類需求聽起來簡單,但確實(shí)能大大提升語言的可用性,消除“我該怎么輸出這個(gè)?”或者“為什么 + 代表整數(shù)加法,而 +. 代表浮點(diǎn)加法?”之類特別勸退的問題。再有,我還想去掉一些沒用的東西,比如對象、鏈表、多態(tài)變體等。這些都是 ReScript/ReasonML 做不到的,而且我上次試用的時(shí)候,ReScript 的開發(fā)體驗(yàn)和錯(cuò)誤消息也沒給我留下深刻印象。
也就是說,我不排除 ReScript 代表著正確方向的可能性。畢竟上次嘗試已經(jīng)是幾年之前了,也許是我記錯(cuò)了、也許它已經(jīng)變得更好了。而且隨著同 OCaml 的剝離,ReScript 確實(shí)成了很好的前端語言選項(xiàng),我有必要再確認(rèn)一下。
對于下一代前端語言,我希望能用一種更系統(tǒng)的方法實(shí)現(xiàn)類型安全。具體來說,我覺得用 Rust 處理非安全代碼塊的方式實(shí)現(xiàn) JS 互操作性的好辦法。基本上,在調(diào)用 JS 的過程中,我們需要將代碼打包在一個(gè)非安全代碼塊中。這會(huì)是個(gè)明確的標(biāo)志,提醒開發(fā)者要認(rèn)真閱讀這段代碼。接下來的目標(biāo),就是在這些指向 JS 庫的非安全代碼塊上實(shí)現(xiàn) bindings。起初這個(gè)過程需要手動(dòng)完成,但后續(xù)應(yīng)該會(huì)有類似 bindgen 和 cxx 的工具出現(xiàn)。
在 JS 中使用非安全代碼塊好像有點(diǎn)反直覺,畢竟 JS 的安全性又不像 C 那么糟糕。但很多人似乎沒意識(shí)到,安全的意義并不僅限于安全本身。所謂安全,是指可以任意使用一個(gè)值、而不必?fù)?dān)心其是否為 null 的保障能力。所謂安全,是在不致引入 Bug 或混亂的前提下保證可變性的能力。Rust 的非安全塊概念允許用戶既維護(hù)自己的安全區(qū),又能與大量非安全代碼交互。下一代瀏覽器語言也該做到這一點(diǎn)。
至于運(yùn)行時(shí)檢查,我覺得它仍然物有所值。我們已經(jīng)在 JS 當(dāng)中進(jìn)行過大量模式驗(yàn)證,只是以往只能通過 zod 這類臨時(shí)性機(jī)制完成。在下一代前端語言中,這類功能也許是在運(yùn)行時(shí)出錯(cuò)時(shí)對語言類型執(zhí)行自動(dòng)轉(zhuǎn)換,也許能對 JS 值進(jìn)行模式匹配。
對于 WebAssembly,我還是很看好它的發(fā)展前景的。但要說它一定能成為瀏覽器的通用運(yùn)行時(shí),我個(gè)人還是持懷疑態(tài)度。也許未來我的態(tài)度會(huì)有轉(zhuǎn)變,但目前我更多是將 Wasm 看作一種硬件加速器。
當(dāng)用戶的高強(qiáng)度計(jì)算任務(wù)要求調(diào)用固定寬度整數(shù)和靜態(tài)函數(shù)時(shí),大家就會(huì)使用 Wasm;這就像在需要執(zhí)行并行計(jì)算時(shí),大家會(huì)選擇 GPU 一樣。在這樣的模型中,我看到了支持異構(gòu)編譯的潛力——其中部分代碼可以被編譯成 JS,另一部分代碼則可編譯為 Wasm。這項(xiàng)工作可以由用戶顯式完成,由分析自動(dòng)完成,甚至可以即時(shí)完成。通過對 JS 和 Wasm 代碼的同時(shí)控制,編譯器就能最大限度減少跨越語言邊界的次數(shù),從而提高性能水平。我覺得未來甚至可以有某種機(jī)制將部分代碼發(fā)送給 WebGPU。
在這樣的模型之上,也許我們可以更輕松地編寫計(jì)算密集型程序,比如機(jī)器學(xué)習(xí)模型、電子游戲和渲染軟件。
這種對 Wasm 和 JS 進(jìn)行分別編譯的概念,可以在下一代前端語言中體現(xiàn)出來。我希望其中能有顯式整數(shù)和浮點(diǎn)類型,最好還能有 Rust 中 usize 那樣的顯式索引類型。這樣如果需要把代碼編譯成 Wasm,新語言就能利用 Wasm 的固定寬度整數(shù)。
還有另一種可能性,就是為語言創(chuàng)建一個(gè)子集,在這里整合閉包、垃圾收集等動(dòng)態(tài)特性以提升 Wasm 編譯質(zhì)量。要跟這個(gè)子集交互,開發(fā)者需要使用 unsafe 代碼塊,比如 strict 塊,或者讓該子集通過 dynamic 塊跟外部代碼交互。這些都是假設(shè),但我覺得其中確有探究的價(jià)值。
這種新語言可能會(huì)用 Rust 來實(shí)現(xiàn)。畢竟我個(gè)人是 Rust 的粉絲,而且相信代數(shù)數(shù)據(jù)類型、相對更高的代碼性能、受限但可用的可變性,以及比較豐富的庫組合足以支撐起一套優(yōu)秀的編譯器。
如果 Wasm 后續(xù)發(fā)展得夠好、性能幾乎逼近原生水平,那我也會(huì)考慮使用由編譯為高速 Wasm 代碼的語言子集來引導(dǎo)編譯器。但這應(yīng)該不著急,畢竟一個(gè) Rust 編譯器應(yīng)該就夠用好多年了。
大家可能已經(jīng)注意到,類型安全和 Wasm 部分其實(shí)就是在從系統(tǒng)語言(例如非安全概念和硬件加速)中汲取靈感,再把它們應(yīng)用到基于瀏覽器的語言當(dāng)中。這是設(shè)計(jì)使然,畢竟不少最有趣的編程語言都是從系統(tǒng)層面衍生出來的。我只希望這些好點(diǎn)子也能在瀏覽器上有所體現(xiàn)。
這里我要澄清一下,我所指的下一代前端語言絕不是單一語言,我希望能有多種語言齊頭并進(jìn)、朝著前面提到的方向共同探索。我想激勵(lì)更多朋友在瀏覽器語言領(lǐng)域不斷創(chuàng)新。當(dāng)然,我個(gè)人也會(huì)參與其中,目前正在研究的是名叫 vicuna 的實(shí)現(xiàn)方案,但還處于非常早期的階段。
原文鏈接:
https://uptointerpretation.com/posts/the-next-browser-language/
*請認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。