LSR 012 - 元组类型规范

基本信息

  • LSR 编号 012

  • 标题 元组类型规范

  • 作者 Ziyang-Bai

  • 状态 草案

  • 类型 标准规范

  • 创建日期 08-09-2026

  • 归属项目 编译器、标准库

摘要

定义 Lamina 元组类型。元组是固定长度、按位置索引、创建后不可变的匿名积类型,可用于函数返回、临时组合和模式匹配 [1]。本规范同时规定元组与分组、函数实参、数组及区间构造之间的语法边界。

技术规范

1. 范围

元组用于组合少量按位置区分的值。元组的长度和各位置元素类型共同组成其类型。元组字面量包含至少两个元素;分组、函数调用、数组和区间分别使用各自的语法规则。

2. 元组类型

元组类型由一组有序元素类型组成。

(int, text)
(int, text, Expr)
  • 元组长度固定

  • 元组元素可以是不同类型

  • 元组类型由长度和每个位置的类型共同决定

  • 元组值默认不可变

  • 元组类型是结构类型;元素类型序列相同的两个元组类型相同

3. 元组字面量

元组字面量使用圆括号,并以逗号分隔元素。

let pair = (1, "one")
let triple = (1, "x", true)
  • 非空元组按元素表达式推导类型

  • 元组字面量至少包含两个元素

  • 单元素圆括号表达式按分组表达式解析

  • (a, b) 始终解析为二元素元组

  • 函数名后紧跟的 f(a, b) 按函数调用解析

  • std.interval_open(a, b) 是普通函数调用,其结果为开区间 [4]

let a = (1)      # 分组表达式,类型为 int

4. 元数

元组字面量的元数至少为二。(value) 是分组表达式;f() 是零实参函数调用。函数的返回语义由核心语言规范定义 [1]。

5. 元组访问

元组元素按位置访问,索引从 1 开始,与 Lamina 现有线性代数索引规则保持一致。

let p = (10, "x")
let a = p.1
let b = p.2
  • 元组索引必须是编译期常量正整数

  • 第一个元素的位置为 1

  • 访问位置超过元组长度是编译错误

  • 元组位置访问读取创建元组时绑定在该位置的元素

6. 元组解构

元组可在 let 和 match 中解构。

let (x, y) = (1, 2)

match value {
    (a, b) => a + b
}
  • 解构模式长度必须与元组长度一致

  • _ 可忽略对应位置

  • 解构绑定的变量类型由对应位置推导

  • 解构保持原元组值,并为各位置创建对应绑定

7. 函数返回元组

函数可以返回元组作为单一返回值。

func divmod(a int, b int) -> (int, int) {
    return (a / b, a % b)
}

let (q, r) = divmod(10, 3)
  • Lamina 仍然是单返回值语言

  • 多个按位置区分的结果应使用元组返回;元素类型可以相同或不同

  • 多个同类型、无序数学结果应使用集合返回 [3]

  • 需要表达命名分支、成功或失败状态时应使用 ADT [2]

8. 相等性与哈希

元组按位置结构比较。

  • 两个元组长度不同,则类型不同

  • 两个同类型元组逐位置相等时,整体相等

  • 只有所有元素可比较时,元组才支持 ==

  • 只有所有元素可哈希时,元组才可作为哈希键

9. 求值与存储语义

元组字面量的元素表达式按源码从左到右各求值一次。元组值创建后,元素位置和元素绑定保持不变。

  • 元组的不可变性是浅层不可变;元素若引用可变对象,该对象仍遵循自身语义

  • 实现可以内联、装箱或共享元组存储;各种表示具有相同的求值顺序、结构相等和可观察生命周期行为

  • 跨模块接口必须保留元组长度、元素顺序和每个位置的静态类型

10. 与数组、集合和区间的区别

类型

长度

元素类型

顺序

主要用途

元组

固定

可异构

有序

多值组合

数组

可变或运行期长度

通常同构

有序

程序式序列

集合 [3]

运行期大小

同构

无序

去重数学集合

区间 [4]

两个端点

同构

有序边界

表示连续或离散范围

11. 诊断

实现至少应区分下列错误:

  • TupleArityMismatch:解构模式长度与元组长度不同

  • TupleIndexNotConstant:位置访问不是编译期常量

  • TupleIndexOutOfBounds:位置不在 1 到元组长度之间

  • TupleAssignment:试图修改元组元素绑定

  • TupleTypeMismatch:目标元组类型与元素类型序列不兼容

错误名称可以映射到实现的统一诊断系统。

12. 兼容性

(a, b) 统一表示元组。原开区间写法 (a, b) 迁移为 std.interval_open(a, b) [4]。

13. 引用