奧推網

選單
科技

深度開源社群公佈其自研程式語言 Unilang,目前處於起步階段

IT之家 9 月 12 日訊息,有IT之家網友發現,深度開源社群之前已經在 Github 和 gitee 公佈了旗下自研程式語言 ——Unilang,同時還包括相關直譯器,講解了 Unilang 文件和參考實現方式。

官方在庫中的描述是“新程式語言”,是“為適應更有效和靈活開發桌面環境應用的提出的通用目的程式語言專案”,旨在更好地幫助當前桌面應用開發者,宿主環境為 MSYS2 MinGW32 和 Linux。

據介紹,深度團隊由於 C / C++、ECMAScript 等最流行的一些標準化語言具有沉重的歷史包袱,且不具有足夠擴充套件語言自身的能力以兼顧其需求;Dart 等專為類似方案設計的語言在一些基本設計上的決策(如依賴全域性 GC )使之無法完全適合一些重要場景;其它的一些通用目的語言,如 Rust 和 Go ,並沒有配套提出 GUI 解決方案。

因此,他們希望在能滿足需求的基礎上,帶來一種新的語言,使它能以更深刻的方式真正地實現通用性 —— 透過減少為個別問題領域準備的原生的特設的 (ad-hoc) 特性,而以更普遍的基本特性集取而代之的方式。

Unilang 是為了統籌解決現有不足的新的方案中的語言部分,主要特色有:

作為動態語言,提供相對其它語言更強的語言層次上的可擴充套件性。

透過使用者定製語言的功能,可以有效限制非預期的動態特性,最終得到和大多數靜態語言接近的開發體驗上的優勢,同時避免靜態語言核心規則帶來的不便。

允許在已部署 Unilang 程式的環境中透過新增庫補全現有語言特性,而不需要重新部署工具鏈的實現。

提供一個基礎語言,並以庫的形式擴充套件這個語言而得到實用的特性集。庫預期由本專案和使用者提供。

大多數語言中需要修改語言核心規則提供的特性,在 Unilang 中預期只需要使用者使用 Unilang 語言編寫的庫解決,例如靜態型別檢查可以透過使用者程式提供。

類似 C 和 C++ 而不同於 Java ,不明確要求或假定翻譯和執行的具體形式。實現使用編譯、解釋和何種映像格式載入等實現細節對核心語言規則透明。

不預設如 C 和 C++ 那樣明確的翻譯階段 (phases of translation) 。不需要單獨階段展開的宏 —— 配合支援一等環境的函式即可取代宏。

支援同像性 (homoiconicity) ,允許程式碼即資料 (code as data) 的方式程式設計。

函式是一等物件 (first-class object) 。

環境 (environment) 對變數繫結具有所有權。支援作為一等物件的一等環境 (first-class environment) 。

支援類似 C++ 的物件模型和(當前不被檢查的)不安全所有權語義。

和 C# 或 Rust 等不同,不提供一種特設的 unsafe 關鍵字標記“不安全”的程式碼段落,最基礎的特性預設是“不安全”的。

安全性並非由語言唯一地定義,允許使用者透過擴充套件型別系統等方式實現自定義的不同種和程度的安全性。

不要求全域性 GC ,同時語言的一個子集允許和 C++ 同等層次的“不安全”但能確保確定性的資源分配。

沒有原生提供針對不安全操作的靜態檢查,但是語言的可擴充套件性允許直接實現型別系統或者自動證明更強的記憶體安全。未來可能作為庫一併提供。

語言規則仍然允許引入依賴 GC 的互操作。特別地,允許引入多個非全域性的 GC 示例。

支援正式意義上的 PTC ,而不需要使用者程式內對棧溢位等未定義行為進行變通。

主流語言中,沒有依賴全域性 GC 的語言實現都沒有提供類似的保證。

使用隱式的潛在型別 (latent typing) 而非顯式的清單型別 (manifest typing) 。

在擴充套件前,作為實現細節,已允許蘊含型別推斷 (type inference) 消除一些型別檢查而不影響程式語義。

允許使用者程式擴充套件型別標註 (type annotation) 的語法和相關檢查。

這自然地避免使用者擴充套件的型別系統和原生規則衝突,而保持可擴充套件性。

表示式和 C++ 類似但略有不同的值類別 (value category) ;但和 C++ 不同,不是靜態確定的表示式的屬性,而是跟隨物件的動態元資料。

類似 C++ 的 const 型別限定符,透過左值引用的物件允許標記為不可修改(只讀),而不是如 Rust 等語言預設約定值不可變 (immutable) 。

類似 C++ 的消亡值 (xvalue) ,透過左值引用的物件允許標記唯一,而允許其中的資源被轉移。

原理 以上代表性的選型決策中,一個共通的方法是比較不同方向的擴充套件之間的技術可行性 —— 並選取容易擴充套件的選項。否則,即便可行,也有許多本應避免的無效的工作。

因此,語言首先要求 PTC 以使其實現有足夠的可用性,而不鼓勵巢狀的不可靠的實現。

注意對 PTC 不可靠的實現方式在其它方面仍可能很成功(如翻譯 ECMAScript 方言的 Babel )。因此,大多數其它特性並沒有(也不需要有)如 PTC 需要基本規則明確擔保的地位。

因此,語言首先排除對全域性 GC 的依賴。

例如,用 unsafe 等特設語法標記“不安全”的語言中,通常會放棄語言定義的任意安全保證,而不能選擇保留其中的一部分。即便忽略這個問題,語言也缺乏機制允許使用者提供更嚴格的保證。

再如,預設不可變的資料結構雖然能保證 const correctness 這樣的“正確性”(一種保持被限定的不可變性質不被丟棄的型別安全性 (type safety)),卻忽略對“不可變”的定義描述不充分而不能讓使用者程式擴充套件的問題 —— 很多情形下,不可變僅僅需要是一種等價關係,而並非不可修改。

因此,基礎語言預設是不安全的。

若語言允許使用者表達“一些具有不同表示的值被視為等價”,則最佳化的適應性會自然地擴充套件。

這蘊含不可變性只有一種,除非修改型別系統設計,放棄原有的不可變定義並重新引入類似 C++ const 的限定符機制(“更困難”的情形)。

這裡用 const_cast 這樣的不安全轉換取消 const 引入的型別安全保證並自行假定不會破壞不可變性,是個無奈的變通(“更困難”的情形,且無法恢復型別安全性而效果更差)。

這可能導致具體的不可修改性被濫用,例如 C++ 標準庫關聯容器的鍵型別實際上不需要符合 C++ 的 const ,因為鍵的不可變確切地由比較關係匯出的等價關係定義,但型別系統無法區別兩種情形。這過度地限制了鍵上的本應允許的操作。

預設不可變的型別系統,如 Rust 的設計,則更根本地在型別組合構造上阻止了擴充套件的方向。

這也限制了現有的實現的常量傳播 (const propagation) 的最佳化範圍,因為原則上這裡的“常量”只關心替換能保持變換前後的語義等價性 (semantic-preserving) ,而不在意具體的值是否相等。

因此,基礎語言中的物件預設可變。

因此,基礎語言首先被設計為動態語言。

設計一個靜態語言,然後新增一些規則把它偽裝成具有足夠動態特性的動態語言,遠遠難於在動態語言上新增規則而得到靜態語言的特性集。

從一個標記放棄某種保證的上下文中新增證明恢復某種保證(且不和其它保證衝突),比從一個已知不具有保證的上下文新增證明以確保保證更困難。

在一個已經要求全域性 GC 的語言中排除 GC ,遠遠難於在不依賴 GC 的語言規則基礎上新增和 GC 互動的能力(特別是 GC 允許使用者定製時)。

在一個沒有 PTC 保證的語言實現中新增擴充套件基本是不可行的,除非重新實現最核心的求值規則在內的邏輯(例如,再新增一個執行引擎)。

和 C++ 具有良好的互操作性。

當前直譯器(執行時)使用 C++ 實現。

結合物件模型,能確保 Unilang 物件和 C++ 物件的對應。

語言繫結主要關注已知 ABI 的 C / C++ API 。

為保持通用性,Unilang 不內建提供 GUI 功能,而透過庫提供相關 API 。當前計劃中,Unilang 將會支援基於 Qt 的繫結的庫,以便銜接過渡現有的一些桌面應用專案。Unilang 的語言設計保持足夠的抽象能力和可擴充套件性,允許在未來直接實現 GUI 框架。