灵活的元编程与 Rhombus
[仅限 LWN 订阅者内容] 类 Lisp 语言历史上在元编程和灵活性方面一直走在世界前列。虽然许多现代语言采用了宏的思想,但像 Racket 这样的类 Lisp 语言仍在不断推进,试图使宏尽可能容易地融入日常程序。另一方面,Lisp 的最小化基于括号的语法可能难以适应——以至于有时人们会说 Lisp 代表“许多烦人的愚蠢括号”。Rhombus 是一种新编程语言,旨在将二者的优点结合起来,将 Racket 的元编程能力与简单的 Python 风格语法和合理的标准库默认值结合在一起。该项目属于更广泛的 Racket 项目,后者“根植于学术界”。在 Rhombus 的 43 名贡献者中,最活跃的两位分别是来自犹他大学的 Matthew Flatt 和来自香港中文大学的 Wing Hei Chan。 Rhombus 作为教学工具在他们的大学使用;Chan 独立贡献于 Rhombus,且实际上并不在香港中文大学的计算机科学系工作。尽管如此,该语言的目标是超越单纯的学术练习。开发得到了 Racket 编程语言基金会的支持,该基金会旨在使 Racket 和 Rhombus 适合实际的专业使用。尽管该语言仅在 6 月 22 日庆祝了 1.0 版本的发布,但已经有一套部分用其编写的 Economancy 卡牌游戏工具,此外还有其他非学术用途。Rhombus 的核心可在 MIT 或 Apache 2.0 许可下获得,尽管它是建立在 Racket 运行时之上,后者在一些动态库中包含 LGPL 3.0 代码。对 Racket 大量基础设施的重用意味着,它已经拥有大量可用的库,以及一个优化过的编译器。Rhombus 程序可以解释执行、编译为字节码或编译为本地机器代码。Rhombus 与 Racket 的一个不同之处,除了语法外,就是其默认数据结构的选择。类 Lisp 语言通常使用单向链表作为核心数据类型,这带来了效率问题。Rhombus 使用基于不可变树结构的列表,使许多操作的时间复杂度为对数时间。此外,标准库中还提供了平坦的可变数组、基于树的映射和集合以及基于哈希的映射和集合。没有 AI 的浪费,所有内容:今天就订阅 LWN。 LWN 一直以来都注重质量而非数量;我们需要您的帮助来继续发布关于 Linux 和自由软件社区的深度、以读者为中心的文章。请今天订阅以支持我们的工作,保持 LWN 的运营;我们提供一个免费的一个月试用订阅,以帮助您开始。 语法 Rhombus 的语法与 Python 相似,都是基于缩进,并使用“:”来指示缩进块的开始。一个小的不同之处是,Rhombus 使用“|”符号来分隔 if 表达式和类似上下文中的分支。最清晰的解释方式可能是通过示例(阶乘函数的实现): fun factorial(n): if n <= 1 | 1 | n * factorial(n - 1) 更加命令式的程序员可能更喜欢下面使用 for 循环的版本。请注意使用的是包含范围 1..=n,而不是更常见的排除范围 1..n。 fun factorial(n): def mutable p = 1 for (i in 1..=n): p := p*i p 默认情况下,变量是不可变的,因此 mutable 绑定操作符是必要的,以允许该循环更改 p 的值。然而,这个示例可以简化。Rhombus 的 for 循环支持一种在类 Lisp 语言之外不常见的特性:用于将每次循环的结果组合成循环自身最终值的可选“归约器”。math.product 归约器将循环返回的所有值相乘,使得可以写成: fun factorial(n): for math.product (i in 1..=n): i 这一能力意味着 Rhombus 对于其他语言中存在的列表推导的对应功能,仅仅是一个使用 List 归约器将结果收集成列表的 for 循环。for 循环还可以使用 all 或 any 归约器生成映射、集合甚至布尔值。在典型的编程语言中,人们可能期望这种内置语法在标准库提供的类型上工作,而不适用于用户定义类型。然而,Rhombus 的宏可以用来扩展几乎所有部分的语言,包括创建新的归约器。大多数程序可能不需要这样做,但在能够简化程序时拥有这个选项是不错的选择。 宏 Rhombus 中的宏使用单引号生成表示 Rhombus 代码片段的语法对象,使用“$”来表示占位符。与传统的类 Lisp 语言使用列表表示代码不同,Rhombus 的语法对象是它们自己的数据类型。这使得它们能够携带
本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。
☕请我喝杯咖啡