LSR 008 - 量纲剥离(Unit Stripping)规范

基本信息

  • LSR 编号 008
  • 标题 量纲剥离(Unit Stripping)规范
  • 作者 Ziyang-Bai
  • 状态 草案
  • 类型 标准规范
  • 创建日期 04-05-2026
  • 归属项目 编译器、通用

摘要

定义带量纲数值到无量纲数值的剥离路径,覆盖 as numas scalar

技术规范

1. 设计目标

  • 为带量纲值提供单一、明确、可预测的剥离语法
  • 与现有 as <unit> 单位转换保持组合性
  • 剥离仅显式触发,精度与安全边界清晰

2. 语法

2.1 基础语法

expr as num
expr as scalar

规则:

  • as num:先转换到 SI 基准量值,再移除单位签名
  • as scalar:仅移除单位签名,不进行数值缩放

2.2 与单位转换组合

(expr as <target_unit>) as num

规则:先转换到目标单位,再剥离为纯数值。

3. 语义定义

3.1 默认基准

  • expr as num 采用 SI 基准量值
  • 例:10<km> as num 的结果是 10000
  • 对抽象基单位(如 scoretoken),as num 采用该基单位自身刻度
  • 例:10<score> as num 结果为 10

3.2 目标单位下剥离

  • 若用户希望在某单位刻度下得到纯数值,必须先显式转换单位
  • 例:(10<km> as <km>) as num 结果为 10
  • 抽象单位之间仅在存在显式比例定义时允许转换

3.3 as scalar 语义

  • expr as scalar 保留当前显示刻度,仅移除单位标签
  • 例:10<km> as scalar 结果为 10
  • 适用于符号推导或公式整理,保持当前刻度,降低系数膨胀

3.4 编译期降级(与 LSR-000 对齐)

  • 量纲在编译期追踪,运行期普通数值不携带单位标签
  • as numas scalar 在 Codegen 前应降级为纯数值表达式

4. 类型规则

  • 输入必须是带量纲或无量纲的数值类型(num 及其子层级)
  • 输出类型为无量纲 num
  • 对非数值类型(如 vector, matrix, table, set, text, bool)使用 as numas scalar,编译报错 UnitStripTypeMismatch

5. 与外部函数/底层操作的交互

5.1 外部函数调用

当外部函数仅接受无量纲参数时,调用端必须显式剥离:

let dist = 1200<m>
let raw = dist as num
let r = c_ext_fft(raw)

5.2 位运算/底层数值 API

位运算和底层原语仅接受无量纲数值;带量纲值必须先 as num

let t = 8<s>
let bits = bit_and((t as num), 3)

规则:外部函数若要求保留当前单位刻度数值,使用 as scalar

6. 安全约束与错误模型

  • UnitStripTypeMismatch: 作用于非数值类型
  • UnitStripOverflow: 剥离过程发生表示范围溢出(实现相关)
  • UnitStripInvalid: 单位转换阶段失败(例无效目标单位)
  • UnitStripLegacySyntax: 使用了废弃语法 as num<_>

规则:

  • 单位维度检查由上游运算与 as <unit> 阶段完成
  • as num 会按 SI 基准缩放后再剥离,as scalar 仅剥离标签

7. 语法约束

  • 仅允许 expr as numexpr as scalar

8. 示例

let speed = 20<m/s>
let raw_si = speed as num                 # SI 基准量值
let raw_kmh = (speed as <km/h>) as num    # km/h 刻度数值
let raw_keep = speed as scalar             # 保留当前刻度值

func second2hour(s num<s>) -> num<h> {
    return ((s as num) / 3600) as num<h>
}

9. 与其他 LSR 的关系

  • LSR-000:在量纲系统章节引用本规范,定义主入口
  • LSR-003:扩展接口中若需无量纲实参,可按本规范显式剥离
  • LSR-007:=== 不依赖单位剥离语义,二者正交