Show HN:Numbat – 一种将物理维度作为类型的编程语言

一门名为 Numbat 的新语言旨在将物理维度和单位作为类型,从而通过编译期检查捕获诸如把米与秒相加、或在物理公式中误用常量之类的错误。评论者将其与 F#、Rust、Julia、C++、Nim、Ada 中的单位系统,以及 GNU Units 和 Frink 等工具进行比较,权衡了专用、静态类型 DSL 与嵌入通用语言的库之间的利弊。他们还探讨了更棘手的边界情况——例如日历时间与时长、货币换算,以及带单位的线性代数——指出这一方法今天的强项,以及类型系统和库还需要如何继续发展。

“物理”单位和维度的范围

  • 讨论焦点在于光、温度和时间是否算作“物理”量,还是仅仅算空间相关;线程中的共识倾向于将“物理”理解为“由物理学描述的”,而不只是 3D 空间。
  • 有人提到相对论和四维向量,论证时间与空间紧密耦合。
  • 也有人反驳那些挑战时空的边缘物理主张,指出它们并非主流。

现有生态与“重复造轮子”

  • 许多人指出已有类似的单位/维度系统:Python(Pint、astropy.units)、F# Units of Measure、Rust 的 uom、Julia 的 Unitful.jl、Scala 的 Squants、Nim(Unchained)、GNU units、Ada 的维度分析、基于 C++ 模板的单位系统、Frink,以及之前的项目 Insect。
  • 有人认为 Numbat 是多余的;也有人指出,作为专用、静态、开源并面向 WebAssembly 的项目,它有自己的定位。

类型系统、数学函数与角度

  • Numbat 中的三角函数和超越函数只接受无量纲标量;传入带单位的量会被视为很可能是错误。
  • 角度被视为可转换为标量(弧度、度、圈数);同时也明确承认“角度是否无量纲”仍有争议。

时间、月份与年份

  • 月份和年份被建模为平均时长(例如,公历年 ≈ 365.2425 天)。
  • 一些评论者称这是一种含糊的“单位混淆”,并区分“时间上的”与“日历上的”单位,指出闰日、闰秒、夏令时、恒星年与回归年等问题。
  • 也有人为这种简化方式辩护,认为它更务实,并警告不要把完整的日历复杂性拖进类型系统。
  • Numbat 目前将时间视为时长,而不是日历日期;还没有“今天 + 14 天”这类日历 API。

线性代数与异构单位

  • 经典难题:向量/矩阵中的各分量拥有不同单位(例如经济投入产出模型、微分算子)。
  • Numbat 目前还缺少聚合类型(向量、矩阵)。大家承认这个问题可以解决,但“很棘手”。
  • 讨论指出,许多静态类型系统默认容器内单位同质,这与现实中的线性代数相冲突。

货币与现实世界建模

  • 货币被作为一个单位支持,并通过欧洲央行获取实时汇率。
  • 有人觉得这是个不错的特性;也有人认为,与真实金融/经济的复杂性相比,这仍然很浅层。

易用性、语法与热情

  • 有人称赞交互式 CLI、丰富的单位目录、Unicode 运算符(×、⋅、÷)以及清晰易读的介绍。
  • 一些用户表达了强烈的热情和支持,包括赞助,并认为 Numbat 是一个用于单位感知计算的优秀计算器/DSL。