速递!深度开源社区公布其自研编程语言 Unilang,目前处于起步阶段

时间:2022-09-12 09:53:45       来源:搜狐号-IT之家

IT之家 9 月 12 日消息,有IT之家网友发现,深度开源社区之前已经在 Github 和 gitee 公布了旗下自研编程语言 ——Unilang,同时还包括相关解释器,讲解了 Unilang 文档和参考实现方式。

官方在库中的描述是“新编程语言”,是“为适应更有效和灵活开发桌面环境应用的提出的通用目的编程语言项目”,旨在更好地帮助当前桌面应用开发者,宿主环境为 MSYS2 MinGW32 和 Linux。

据介绍,深度团队由于 C / C++、ECMA 等最流行的一些标准化语言具有沉重的历史包袱,且不具有足够扩展语言自身的能力以兼顾其需求;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 不可靠的实现方式在其它方面仍可能很成功(如翻译 ECMA 方言的 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 框架。

关键词: 类型系统 可扩展性