LSR 006 - Lambda 表达式与类型推导规范

基本信息

  • LSR 编号 006

  • 标题 Lambda 表达式与类型推导规范

  • 作者 Ziyang-Bai

  • 状态 草案

  • 类型 标准规范

  • 创建日期 04-05-2026

  • 归属项目 编译器、通用

摘要

定义 Lambda 的语法、类型推导、闭包捕获与管道交互。Lambda 返回类型由函数体表达式和调用上下文确定。

技术规范

1. 设计目标

  • 提供轻量匿名函数语法

  • 与管道 |> 平滑协作

  • 在保持静态强类型前提下支持局部推导

2. 语法

2.1 基础语法

|x| -> x + 1
|x, y| -> x * y
|x num, y num| -> x + y

规则:

  • |...| 为参数列表

  • -> 右侧为单表达式函数体

  • Lambda 自身是表达式,可赋值、可传参、可返回

2.2 与命名函数语法的关系

  • 命名函数:func name(params...) -> ReturnType { ... }

  • Lambda:|params| -> expr

Lambda 返回类型由函数体表达式推导。

3. 类型推导规则

3.1 参数类型

  • 可显式标注:|x num| -> x + 1

  • 可省略标注:|x| -> x + 1

  • 省略时依赖上下文约束推导参数类型

  • 数学参数和返回值的基本静态类型统一为 num;精确数、符号表达式、关系和近似值不产生不同的基本签名

  • |x int| -> x + 1 中的 int 是 num 上的整数值约束;frac、real、complex 同样是值约束,不是独立基本数学类型

  • 值约束参与调用和返回校验;静态可证时提前检查,其余在运行期验证。确定违反时报 DomainError 或 InvalidArgument,仍未决时报 Inconclusive

  • 基本签名及参数个数相同的函数不得仅凭值约束静态分派;符号参数可以满足已证明的约束,不要求其具有某种内部数值表示

  • 函数值兼容性必须保留参数值约束及静态量纲契约;不能仅因基本类型都是 num 就把只接受 int 或特定量纲的函数用于更宽的参数上下文

  • 普通有副作用函数在参数约束未决时报 Inconclusive,不自动转为符号调用;只有已声明的数学求值接口可按其契约保留未求值结果

3.2 返回类型

  • 返回类型由 -> 右侧表达式推导

  • 返回类型需可由上下文确定

  • 若无法确定,编译报 LambdaTypeAmbiguous

3.3 上下文定型(contextual typing)

  1. 赋值上下文

let f = |x num| -> x^2
  1. 参数上下文

let out = map(vec[1,2,3], |x| -> x^2)
  1. 返回上下文

func make_inc() -> (num -> num) {
    return |x| -> x + 1
}

4. 与管道 |> 的交互

4.1 一元函数管道

let res = vec[1,2,3,4]
  |> filter(|x| -> x % 2 == 0)
  |> map(|x| -> x^2)

管道采用首参插入规则:x |> f(a, b) 等价于 f(x, a, b),x |> f 等价于 f(x)。左侧先求值一次,其余实参按源码顺序求值,再按普通调用规则绑定和检查;不要求 f(a, b) 先产生函数,也不自动进行默认实参补全或柯里化。上述示例分别调用 filter 和 map 的二实参形式。

谓词 x % 2 == 0 的基本类型为 num,表示数学关系;要求确定判真的谓词接口按核心条件规则处理它,未决时报 Inconclusive,不把未决关系当成 false。

4.2 歧义与优先级

  • |> 左结合

  • 当 Lambda 参数列表与外层调用产生歧义时,必须加括号

let res = data |> map((|x| -> x + 1))

5. 闭包捕获规则

  • Lambda 可捕获外层 let 绑定(只读)

  • 外层 var 更新通过显式返回值传递

  • 若需更新状态,必须显式通过返回值传递新状态

let base = 10
let add_base = |x| -> x + base

6. 与值语义/COW 的关系

  • 捕获复合类型(vector, matrix, table, set )见 LSR-000 [1] 第 4.6 节

  • 只读捕获保留捕获时的值,不提供可写子路径;后续通过其他 var 根路径修改容器不得改变已捕获的值

  • Lambda 可将捕获值绑定为局部 var 后修改;修改只改变该局部值,不回写捕获来源

  • 共享、复制、写时复制或唯一所有权优化由实现选择,不规定必须复制的时机,也不提供数学容器的可观察对象身份

7. 错误与诊断

  • LambdaTypeAmbiguous: Lambda 参数或返回类型无法由上下文确定

  • LambdaCaptureMutation: 非法写入外层 var 捕获

  • LambdaArityMismatch: 传入参数个数与 Lambda 形参不一致

8. 引用