1 个不稳定版本

0.1.0 2019年1月15日

#13 in #language-design

MIT/Apache

390KB
6.5K SLoC

Lark

Lark 是一个实验性的编程系统,包括一种编程语言、一个编译器、构建系统、IDE 支持、以及 VSCode 插件。由于 Lark 是实验性的,并且处于早期阶段,你会发现它的完整性各不相同。

Lark 的主要目标是使用 Rust 作为实现语言,通过实验来探索设计编程语言的新方法。通过关注实现的整体性和广度优先的方法,我们希望找到有用的实现技术,这些技术可能更广泛地有用,尤其是在 Rust 自身的实现技术方面。我们也在探索可能更广泛有用的语言特性方法,但这些探索目前还比较具有推测性。

Lark 从其他语言中汲取了大量的灵感,特别是 Rust 编程语言。与 Rust 类似,它采用了从 Rust 的借用检查器中吸取的权限系统,以帮助确保安全、高效的代码,而无需垃圾回收器。虽然 Lark 并不总是与 Rust 的确切设计相同,但它意图从许多相同的设计公理开始

  • 语言的常用模式不需要垃圾回收
  • 语言在设计上是内存安全的
  • 语言是线程友好的,保证没有数据竞争,并强烈鼓励消除其他类型竞争条件的模式

Lark 作为工具和语言,都被设计成将基本编译器和交互式代码编辑作为首要关注点。

为了实现这一点,Lark 系统大量依赖于 Salsa,这是一个用于高效增量计算的框架。这使得编译器可以请求一些信息,如函数参数的类型,并自动计算它需要的任何派生信息。这使得编译器按设计是增量式的。通过使用 Salsa 描述必要的计算,编译器和语言服务器会自动进行所需的信息服务所需的所有计算。

Salsa 已被用于 实验性的第三方 Rust 分析工具,通过 Lark,我们希望进一步探索 Salsa 使可能的能力。

它看起来像什么?

Lark 仍然非常实验性,许多核心功能可能会改变。尽管如此,当前版本看起来是这样的

struct Adder {
    x: uint
    y: uint

    sum() -> uint {
        self.x + self.y
    }
}

def main() {
    let adder = Adder(x: 4, y: 7)

    debug(adder.sum())
}

目标

当前Lark的目标集中在在Salsa增量计算系统之上构建一个新的编译器。同时,我们也在探索各种利用这一系统的功能,包括IDE支持、编译器和REPL/解释器。

Lark语言旨在获得兼顾表达性和效率的功能,并侧重于语言特性的可读性和可维护性成本。因此,Lark旨在采用80/20规则进行设计:如果一个设计可以在80%的时间内帮助程序员,即使在20%的时间内可能会使某些事情变得稍微繁琐,那么这是有价值的。

此外,Lark被设计为既是一种语言,也是一种系统,将IDE支持作为一个一等特性。

非目标

Lark,尤其是在其预alpha版本中,不打算用于任何商业产品。它而是打算作为一个研究语言使用。

Lark并不打算研究所有编程语言设计的领域,或者广泛积累语言特性。它而是专注于可以良好协同使用的特性集合,并展示它们可以考虑到增量编译来构建。Lark的最初设计者也非常参与并致力于Rust语言,因此它还专注于与Rust的设计目标精神相似的语言特性,以期探索可以启发Rust未来设计的语言设计问题。

在当前状态下,Lark并不试图创建最有效的代码。相反,它将优化推迟到外部编译器。尽管如此,Lark语言设计仍然考虑了效率,并试图避免在实践中会显著降低整个程序效率的设计。

当前状态

Lark处于预alpha阶段。它旨在探索许多感兴趣的领域,但不是对任何一个领域的完整探索。以下是对每个子领域状态的说明

  • 语言特性
    • 条件语句
    • 函数和函数调用
    • 结构体、结构体实例创建、方法和成员访问
    • 字符串
    • booluint
    • 其他
  • IDE支持
    • 语言服务器协议(LSP)支持
      • 查找所有引用(基本完成)
      • 转到定义(基本完成)
      • 重构/重命名(基于上面的查找所有引用)
      • 在输入时显示错误
      • 悬停显示类型
      • (注意:目前尚未实现补全功能)
    • VSCode插件
      • 以上所有LSP功能都支持在VSCode插件中
  • 类型检查器
    • 支持的语言特性之间的基本类型检查
  • 权限检查器
    • 所有权推理
    • 初始化检查
  • 解释器
    • 通过解释器运行Lark代码
    • 交互式REPL
  • 代码生成
    • 输出到Rust
    • 计划
      • 输出到C
      • 输出到WASM(可能)
  • 错误报告
    • Rust样式的错误美观打印器
    • 最小化错误消息
  • 内部测试
    • 编译器测试
    • IDE基于测试
  • 内部设计
    • Salsa基于的增量编译
    • 多线程编译
    • 多线程IDE支持

Lark有多成熟?

Lark仍然处于不稳定/预alpha阶段。它缺少即使在最简单的生产系统中也很常见的最基本的功能。语法可能会发生重大变化。核心概念可能会随着我们从实验中学到的知识而添加、删除或更改。

建议在此阶段不要将Lark用于任何商业环境。

为什么选择Lark?(或者说为什么不作为另一种语言的一部分来做?)

Lark最初是从Jonathan和Yehuda各自创建的多个小型项目发展而来的。一旦两人注意到设计目标之间的强烈重叠,项目就被合并,并且很快就开始包括Niko已经开始工作的增量计算系统Salsa。

最初的动机来自于在现有的语言中看到多个领域,在这些领域中,可以选择不同的设计或实现方案。我们希望那些设计被探索,即使我们不确定那些探索是否会成功。

Lark的设计理念与Rust非常接近,所以我们假设如果Lark证明了功能集的一部分,那么在Rust中实验类似的功能集将是有意义的。尽管如此,Lark的设计决策有时会与Rust有强烈的差异,因此在Lark中成功证明某个功能并不一定意味着可以直接移植到Rust中。

从头开始设计也允许更容易地进行实验,并专注于几个核心原则。

这与Rust有什么关系?

尽管Lark是由参与Rust开发工程师创建的,但它是一个独立的项目。Lark不是一个官方的Rust项目,而是一个为了探索现代语言和工具的可能性而进行的研究项目。

一种看待Lark的方法是类似于Servo和Firefox之间的关系。Servo最初是一个独立的研究项目,后来也将想法和代码反馈给Firefox。

希望Lark中探索的许多技术最终可以被rustc采用,并成为Rust语言中的RFC。

Lark何时会具备功能X?

声明形式、条件和循环在Lark中都是宏。普遍的希望是,宏系统应该能够解锁表达各种能力的能力,而无需必然地增长Lark的核心语言功能。(我们意识到这是一个有争议的观点,并且与Rust的宏模型有很大的不同。)

特别是,Lark使用与Rust类似的HIR设置,这使得少数核心语言原语能够作为大量语法表面的目标。与Rust不同,Lark几乎所有的语法都通过宏实现,这使得可以对外部实验语法形式,以及几乎所有语法的“版本”式演变成为可能。

我该如何帮忙?

如果您想帮忙,有许多领域您可以提供帮助。如果您想参与编译器的开发,您可以查看未解决的问题。您可以阅读有关编译器内部结构的更多信息。

我们还将努力设计我们知道需要设计的领域。我们鼓励人们阅读路线图,并查看正在积极创建的语言部分的积极设计讨论,而不是提出语言功能。

还有许多编码机会,除了直接参与编译器本身的工作之外,包括用额外的测试完善测试套件,为预期可以工作的领域编写示例和报告问题,以及尝试IDE支持。

我们还将尽可能使“任务”问题可用。这些将包含更详细的如何贡献的说明。

许可

Lark同时受Apache 2.0和MIT许可的约束。

有关详细信息,请参阅LICENSE-APACHELICENSE-MIT

依赖关系

~11–21MB
~294K SLoC