LSR 006 - Lambda 表达式与类型推导规范 ================================================================================ 基本信息 -------------------------------------------------------------------------------- - LSR 编号 006 - 标题 Lambda 表达式与类型推导规范 - 作者 Ziyang-Bai - 状态 草案 - 类型 标准规范 - 创建日期 04-05-2026 - 归属项目 编译器、通用 摘要 -------------------------------------------------------------------------------- 定义 Lambda 的语法、类型推导、闭包捕获与管道交互。Lambda 独立推导,返回类型由表达式推导。 技术规范 -------------------------------------------------------------------------------- 1. 设计目标 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 提供轻量匿名函数语法 - 与管道 ``|>`` 平滑协作 - 在保持静态强类型前提下支持局部推导 2. 语法 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2.1 基础语法 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code-block:: text |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`` - 省略时依赖上下文约束推导参数类型 3.2 返回类型 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - 返回类型由 ``->`` 右侧表达式推导 - 返回类型需可由上下文确定 - 若无法确定,编译报 ``LambdaTypeAmbiguous`` 3.3 上下文定型(contextual typing) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 1. 赋值上下文 .. code-block:: text let f = |x num| -> x^2 2. 参数上下文 .. code-block:: text let out = map(vec[1,2,3], |x| -> x^2) 3. 返回上下文 .. code-block:: text func make_inc() -> (num -> num) { return |x| -> x + 1 } 4. 与管道 ``|>`` 的交互 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 4.1 一元函数管道 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code-block:: text let res = vec[1,2,3,4] |> filter(|x| -> x % 2 == 0) |> map(|x| -> x^2) 4.2 歧义与优先级 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - ``|>`` 左结合 - 当 Lambda 参数列表与外层调用产生歧义时,必须加括号 .. code-block:: text let res = data |> map((|x| -> x + 1)) 5. 闭包捕获规则 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Lambda 可捕获外层 ``let`` 绑定(只读) - 外层 ``var`` 更新通过显式返回值传递 - 若需更新状态,必须显式通过返回值传递新状态 .. code-block:: text let base = 10 let add_base = |x| -> x + base 6. 与值语义/COW 的关系 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 捕获复合类型(``vector``, ``matrix``, ``table``, ``set`` )见 LSR-000 第 4.6 节 - 只读捕获不触发复制 - 若 Lambda 内部对局部可变副本突变,触发 COW,不回写原对象 7. 错误与诊断 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - ``LambdaTypeAmbiguous``: Lambda 参数或返回类型无法由上下文确定 - ``LambdaCaptureMutation``: 非法写入外层 ``var`` 捕获 - ``LambdaArityMismatch``: 传入参数个数与 Lambda 形参不一致 8. 与其他 LSR 的关系 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - LSR-000:定义核心类型系统、局部推导总原则与管道运算符 - LSR-005:match 规范来源