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