LSR 000 - Lamina 核心语言规范(草案) ================================================================================ 1. 语言定位 -------------------------------------------------------------------------------- Lamina 是静态强类型、表达式导向的数学 DSL/脚本语言,支持单位系统、代数表达和局部类型推导。 Lamina的主要核心为静态、模块化与数学。 一个 :code:`.lm` 文件就是一个模块。 一个模块可以绑定一个动态库 [1]_。 2. 核心关键字 -------------------------------------------------------------------------------- :code:`let` , :code:`var` , :code:`const` , :code:`unit` , :code:`func` , :code:`return` , :code:`in` , :code:`not` , :code:`loop` , :code:`while` , :code:`break` , :code:`continue` , :code:`if` , :code:`else` , :code:`match` , :code:`sym` , :code:`import` , :code:`use` , :code:`as` , :code:`and` , :code:`or` , :code:`static` 3. 运算符总览 -------------------------------------------------------------------------------- 3.1 基础算术与优先级 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 算术运算符: :code:`+` , :code:`-` , :code:`*` , :code:`/` , :code:`//` , :code:`%` , :code:`^` - 优先级(高到低): 1. :code:`^` (幂运算) 2. :code:`*` (乘法), :code:`/` (除法), :code:`%` (取余), :code:`//` (整除) 3. :code:`+` , :code:`-` 3.2 逻辑与比较 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 标量比较: :code:`==` , :code:`!=` , :code:`<` , :code:`<=` , :code:`>` , :code:`>=` - 广播比较: :code:`.==` , :code:`.!=` , :code:`.<` , :code:`.<=` , :code:`.>` , :code:`.>=` - 逻辑: :code:`and` , :code:`or` , :code:`not|!` - 规则:逻辑运算优先级低于算术运算 - 规则:未加点的比较仅用于标量; :code:`vector` / :code:`matrix` 比较必须使用加点算子 - 优先级(高到低, 低于3.1运算符): 1. :code:`not` , :code:`!` 2. :code:`or` , :code:`and` 3. :code:`==` , :code:`!=` 4. :code:`>` , :code:`<` , :code:`>=` , :code:`<=` 3.3 赋值与绑定 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 赋值: :code:`=` - 绑定: :code:`let` (只读), :code:`var` (可变) - 符号声明: :code:`sym` (类型固定为 :code:`Expr` ) - 优先级:最低 3.4 矩阵与向量运算符 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 线性代数: :code:`*` , :code:`\\` , :code:`/` , :code:`^` - 元素广播: :code:`.*` , :code:`./` , :code:`.+` , :code:`.-` , :code:`.^` - 关系广播: :code:`.==` , :code:`.!=` , :code:`.<` , :code:`.<=` , :code:`.>` , :code:`.>=` - 转置: :code:`'` (共轭转置), :code:`.'` (非共轭转置) - 优先级: 线性代数暂定,元素广播同3.1,关系广播同3.2 3.5 集合相关运算符 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 从属: :code:`in` , :code:`not in` - 子集: :code:`subset` - 并交差: :code:`|` , :code:`&` , :code:`-` - 对称差: :code:`xor` 3.6 函数与流程运算符 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Lambda 箭头: :code:`->` - match 分支箭头: :code:`=>` - 管道: :code:`|>` - 成员访问: :code:`.` .. code-block:: text # 管道符是语法糖 let a = b |> foo; # let a = foo(b); # `.` 左边不是mod, 且右边为方法调用时,也是语法糖 let a = b.m1(); # let a = (typeof b).m1(b); 3.7 运算符分派与歧义约束 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. list-table:: :header-rows: 1 * - 运算符 - 仅适用类型 - 语义 - 歧义处理 * - :code:`/` - :code:`num` - 数值除法 - 若操作数不满足数值或矩阵规则,编译报错 * - :code:`\\` - :code:`matrix` - 矩阵左除(解 :code:`A X = B` ) - 左值必须可作为系数矩阵,维度不匹配或系统无解时报错 * - :code:`/` - :code:`matrix` - 矩阵右除(解线性系统) - 左值必须是矩阵,右值可用于右除,否则报错 * - :code:`^` - :code:`num` / :code:`Expr` - 幂运算 - 集合对称差使用 :code:`xor` * - :code:`^` - :code:`matrix` - 矩阵幂(整数指数) - 非方阵或非整数指数报错 * - :code:`xor` - :code:`set` - 集合对称差 - 集合对称差统一使用 :code:`xor` * - :code:`<` :code:`<=` :code:`>` :code:`>=` :code:`==` :code:`!=` - 标量( :code:`num` / :code:`complex` / :code:`text` / :code:`bool` ) - 标量关系比较 - 操作数为 :code:`vector` / :code:`matrix` 时编译报错,要求使用加点比较 * - :code:`.*` :code:`./` :code:`.+` :code:`.-` :code:`.^` - :code:`vector` / :code:`matrix` 与标量或同形状容器 - 元素级广播 / 哈达玛运算 - 维度不兼容报错 * - :code:`.==` :code:`.!=` :code:`.<` :code:`.<=` :code:`.>` :code:`.>=` - :code:`vector` / :code:`matrix` 与标量或同形状容器 - 元素级关系广播 - 返回同形状 :code:`vector` / :code:`matrix` ,维度不兼容报错 3.8 一元运算符 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 4. 变量、类型与推导 -------------------------------------------------------------------------------- 4.1 类型系统 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 具备自底向上类型推导,多数情况推荐手动标注类型 4.2 局部类型推导规则 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 允许推导:局部 :code:`let/var` 绑定、for 推导式局部变量 - 必须显式:函数参数类型、函数返回类型、模块导出符号类型 - Lambda 与 match 的推导规则由 LSR-006 [4]_ 与 LSR-005 [3]_ 定义 - 推导结果必须为确定类型;约束不足时编译报错 4.3 声明语法 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 变量声明统一 :code:`let|var|const name type = expr` 或者 :code:`let|var|const name = expr` 。 - :code:`let` :只读绑定, 当绑定为对象类型时,仅代表不可再次绑定另一个对象|值,而不是对象本身不可变 - :code:`var` :可变绑定 - :code:`const` :编译期常量声明(只读,要求初始化表达式可在编译期求值) .. code-block:: text let a = 10 let pi_val real = 3.1415 let fraction = 3/2 const TAU = 2 * pi let c = 5/4 let name = "LSR" var counter = 0 counter = counter + 1 a = 20 # 编译报错 4.4 核心数据类型 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. list-table:: :header-rows: 1 * - 类型 - 说明 - 字面量 / 示例 * - :code:`num` - 数值超集( :code:`int` , :code:`real` , :code:`frac` ) - :code:`42` , :code:`114.514` , :code:`1/2` * - :code:`array` - 编程式数组类型 - :code:`[2,5,3]` * - :code:`complex` - 复数 - :code:`3 + 4i` * - :code:`text` - 文本 - :code:`"i love lamina"` * - :code:`bool` - 布尔逻辑 - :code:`true` , :code:`false` * - :code:`set` - 无序去重集合 - :code:`{1,2,3}` * - :code:`vector` - 一维同构数值数组(1 索引) - :code:`vec[1,2,3]` * - :code:`table` - 哈希表(任意可哈希键) - 见 4.5 * - :code:`matrix` - 二维同构数值网络(1 索引) - :code:`mat[1,2;3,4]` * - :code:`Expr` - CAS 符号表达式 - :code:`x^2 + 1` - 在当前定义中, :code:`int` , :code:`bool` , :code:`frac` 为值类型,其他为对象引用类型 - :code:`num` 为代数表达式的类型,但其下 :code:`int` , :code:`real` , :code:`frac` 均为实际类型,也是核心数据类型成员 - Lamina没有浮点数,浮点数只存在于FFI操作中,解释器使用分数模拟有理数运算,无精度损失 4.5 可空类型 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 写法: :code:`T?` ,表示可能为null, 用于判断价值是否为null 必须处理空情况才能正常使用 .. code-block:: text var s text? = null if s != null { #s在此作用域内部,自动变为text类型 } if s == null { } else { #s在此作用域内部,也自动变为text类型 } 4.6 复合类型的值语义与引用语义 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 4.6.1 总规则 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - 复合类型实现采用共享引用,降低拷贝成本 - 只读操作(读取、遍历、计算)不触发复制 - 一旦发生可变写入( :code:`var` 绑定上的突变),若对象被共享,必须先分离副本再写入 4.6.2 赋值语义 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - 赋值后两个变量指向同一底层对象( :code:`is` 可能为 :code:`true` ) - 对其中一个变量做可变写入时,触发 COW,另一个变量保持原值 .. code-block:: text var t1 = table{"x" => 1} var t2 = t1 t2["x"] = 9 # t1["x"] == 1 # t2["x"] == 9 4.6.3 函数传参语义 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - 非值类型参数采用引用传递 - 修改结果通过 :code:`return` 新对象交付调用方 .. code-block:: text func bump(src table[text, int]) -> table { var t = src let v = t["n"] # 返回类型为int?可空类型 # 若为值类型则产生复制,否则为引用 if v != null { t["n"] = v + 1 } t } var a = table{"n" => 0} var b = a |> bump # a["n"] == 0 # b["n"] == 1 4.6.4 与 let/var 的关系 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - :code:`let` :只读绑定,COW 写路径仅由 :code:`var` 触发 - :code:`var` :可变绑定,触发 COW 规则 - 本规则统一适用于 :code:`vector` 、 :code:`matrix` 、 :code:`table` 、 :code:`set` 4.7 容器齐次性约束 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :code:`vector` 与 :code:`matrix` 强齐次,保证类型稳定与 BLAS 友好。 - :code:`vector` 要求所有元素类型一致 - :code:`matrix` 要求所有元素类型一致 - 对数值容器,元素量纲签名也必须一致 示例: .. code-block:: text let ok_v = vec[1, 2, 3] # 合法:同类型同量纲 # let bad_v = vec[1, 2] # 非法:量纲不一致 异构数据建议: - 需要混合不同量纲(如 :code:`[pos, vel]` )时,使用 :code:`table` - 或使用具名复合类型规范 5. 量纲系统 -------------------------------------------------------------------------------- 5.1 声明与运算 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 单位通过尖括号 :code:`<>` 附加于数值后形成复合类型。编译器执行量纲代数(约分、乘除)与加减一致性检查。 单位只能标注在 :code:`num` 类型中,量纲属于类型系统。 量纲只能标在字面量后面,或在声明类型时使用例如 :code:`num` 的形式 .. code-block:: text let dist = 10 let time = 2 let spd = dist / time # let error = 5 + 2 # Dimensional Mismatch 5.2 显式单位转换 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 单位转换必须使用 :code:`as` : .. code-block:: text let v = 20 let v_kmh = v as 5.2.1 用户自定义单位 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 用户可使用 :code:`unit` 声明新单位,支持两种形式: - 抽象基单位: :code:`unit U` - 派生单位: :code:`unit V = expr<...>` .. code-block:: text unit score unit token unit km = 1000 unit min = 60 unit N = 1 unit level = 100 约束: - 单位名在当前命名空间内唯一 - 单位定义要求无环(如 :code:`unit a = 2` 且 :code:`unit b = 3` 形成环) - 抽象基单位可直接创建;派生单位需可归约到已知单位组合(SI 或抽象基单位) - 派生单位必须可归约到已知单位组合(SI 或已声明抽象单位) - 定义成功后可参与 :code:`as <...>` 转换(仅限同量纲) 5.3 底层表示 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 量纲签名在**编译期类型检查阶段**表示为“SI 七维 + 用户基单位”的稀疏指数映射 - 无量纲纯数字对应零向量 - 乘除运算对应向量加减 - 相同量纲不同缩放单位仅允许通过 :code:`as` 显式转换 实现约束: - 运行期普通数值不携带量纲元数据 - 以便复用 BLAS/LAPACK 等高性能线代后端 - 仅 :code:`Expr` (CAS)允许保留量纲符号,用于符号推导中的一致性验证 5.4 量纲剥离(to scalar) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 带量纲值剥离为纯数值的语法与边界由 LSR-008 [6]_ 定义。 .. code-block:: text let dist = 10 let raw = dist as num # SI 基准转换后剥离 let raw_keep = dist as scalar # 仅剥离标签,保持当前刻度 let speed = 20 let raw_kmh = (speed as ) as num 规则: - 默认剥离到 :code:`num` 使用 SI 基准量值 - :code:`as scalar` 仅移除量纲标签,不进行数值缩放 - 若需要特定单位下的纯数值,先做单位转换再剥离 - :code:`as num<_>` 在新规范中非法,必须使用 :code:`as num` 6. 函数 -------------------------------------------------------------------------------- 6.1 函数签名 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 函数签名语法: :code:`func name(param Type, ...) -> ReturnType` .. code-block:: text func kinetic_energy(m num, v num) -> num { return 1/2 * m * v^2 } func second2hour(s num) -> num { return ((s as num) / 3600) as num } 6.2 Lambda 与 match 的规范边界 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 本文件不定义 Lambda 语法与类型推导细则 - Lambda 的语法、类型推导、与管道交互由 LSR-006 [4]_ 单独定义 - match 的语法、穷尽检查、模式系统由 LSR-005 [3]_ 单独定义 7. 控制流与推导式 -------------------------------------------------------------------------------- 7.1 表达式化 if ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :code:`if` 是表达式,必须有 :code:`else` (或提前 :code:`return` 完全覆盖)。 .. code-block:: text let abs_val = if x < 0 { -x } else { x } 7.2 loop 定次循环 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ lamina只有一种循环,就是无限loop循环,其他循环结构均为其语法糖 :code:`loop x { ... }` 表示循环体执行 :code:`x` 次。 :code:`x` 必须是可确定为非负整数的表达式。 .. code-block:: text import std loop { if true { break } } loop 5 { std.println("tick") } ##### let n = 3 loop n { counter = counter + 1 } 规则: - 循环次数在进入循环前求值一次 - 若 :code:`x == 0` ,循环体不执行 - 若 :code:`x < 0` 或不是整数,编译报错 7.3 while 条件循环 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :code:`while cond { ... }` 在 :code:`cond` 为 :code:`true` 时重复执行循环体。 .. code-block:: text var i = 0 while i < 5 { i = i + 1 } 规则: - 每轮迭代前重新计算 :code:`cond` - :code:`cond` 必须是 :code:`bool` 类型,否则编译报错 - 支持 :code:`break` 与 :code:`continue` 7.4 for 迭代与推导式 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 迭代: :code:`for 名字 in 可迭代对象 {...}` 不论迭代还是推导式,其可迭代对象必须包含 :code:`begin()` :code:`next(last iterator)` 和 :code:`end()` 子方法 .. code-block:: text let person = vec[2,4,32,5,6] for num in person { print(num) } # 等价写法: let person = vec[2,4,32,5,6] { let end = person.end() var iter = person.begin() var num = iter.get() while iter != end { print(num) iter = person.next(iter) num = iter.get() } } 推导式语法: :code:`表达式 for 变量 in 可迭代对象 if 守卫条件` .. code-block:: text # 向量推导 let squares = vec[x^2 for x in range(1, 10) if x % 2 == 0] # 集合推导 let abs_set = {abs(x) for x in vec[-1, 1, 2, -2]} # 矩阵推导 let M = mat[i * j for i in range(1,3); for j in range(1,3)] 规则: - 推导式内部为独立词法作用域 - 外部变量访问范围:读取外部 :code:`let` ;外部 :code:`var` 通过显式返回更新 - 迭代器单次求值 8. 向量与矩阵计算 -------------------------------------------------------------------------------- 8.1 定义、拼接与索引 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code-block:: text let A = mat[1,2,3;4,5,6;7,8,9] let v = vec[1,2,3] let A_double = [A, A] let A_stack = [A; A] let element = A[2,3] 8.2 切片 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code-block:: text let row2 = A[2,*] let col3 = A[*,3] let submat = A[1..2,2..3] 8.3 算术与关系广播定义 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 标准线性代数算子: :code:`*` , :code:`\\` , :code:`/` , :code:`^` - 元素广播算子: :code:`.*` , :code:`./` , :code:`.+` , :code:`.-` , :code:`.^` - 关系广播算子: :code:`.==` , :code:`.!=` , :code:`.<` , :code:`.<=` , :code:`.>` , :code:`.>=` - :code:`\\` 与 :code:`/` 分别定义为左除与右除: :code:`A \\ B` 解 :code:`A X = B` , :code:`B / A` 解 :code:`X A = B` - :code:`\\` 、 :code:`/` 与 :code:`^` 采用按类型分派;无法唯一分派时编译报错 - 未加点的关系比较仅用于标量;容器比较必须使用加点算子 .. code-block:: text let X = A \\ B # 线性系统 A X = B let Y = B / A # 线性系统 Y A = B .. code-block:: text let B = A .+ 10 let C = A .* A let D = A * A # A 必须为方阵 let flags = vec[1,2,3] .> 1 # vec[false, true, true] # vec[1,2,3] > 1 # 编译报错(容器比较需使用 .>) 8.4 常用操作 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code-block:: text dot(v1, v2) # 点积 cross(v1, v2) # 叉积(3维) norm(v) # 范数 v1 .+ v2 # 逐元素加法 v .* 2 # 标量广播 matmul(A, v) # 矩阵-向量乘 matmul(A, B) # 矩阵-矩阵乘 inv(A) # 逆矩阵 det(A) # 行列式 9. 集合与逻辑 -------------------------------------------------------------------------------- .. list-table:: :header-rows: 1 * - 运算符 - 含义 - 示例 * - :code:`in` / :code:`not in` - 元素从属 - :code:`2 in {1,2,3}` * - :code:`subset` - 子集关系 - :code:`{1,2} subset {1,2,3}` * - :code:`|` , :code:`&` , :code:`-` , :code:`xor` - 并、交、差、对称差 - :code:`{1,2} xor {2,3}` 预定义数学常量: :code:`pi` , :code:`e` , :code:`phi` 预定义集合: :code:`{R}` , :code:`{Z}` , :code:`{Q}` , :code:`{C}` 10. 数值塔与提升规则 -------------------------------------------------------------------------------- 层级: :code:`Z ⊂ Q ⊂ R ⊂ C ⊂ Expr` - :code:`Int (Z)` :大整数,与 :code:`int` 区别在于其为无限精度 - :code:`Fraction (Q)` :分数(分子分母均为 :code:`Int` ), 与 :code:`frac` 区别在于 :code:`frac` 分子分母均为 :code:`int` - :code:`Real (R)` :实数 - :code:`Complex (C)` :复数 - :code:`Expr` :符号表达式 提升规则: 1. 二元运算中,低层级自动提升到高层级 2. :code:`Expr` 降级需显式转换 3. 除法只有在显式涉及 :code:`Real` 时返回 :code:`Real` 4. 数值提升与单位推导互不干涉 .. code-block:: text let a = 2 + 1/2 let b = 1/2 + 0.5 let c = 2.0 + 3i sym x let d = 5/2 + x 11. Expr 边界与求值 -------------------------------------------------------------------------------- :code:`Expr` 为延迟求值 AST;参与数值运算时整体提升为 :code:`Expr` 。 .. code-block:: text let c = 5 sym x let res = c * x :code:`Expr` 降级必须显式: 1. 代入求值: :code:`expr(symbol => value)` 2. 强制浮点: :code:`evalf(expr)` .. code-block:: text sym x, y let equation = x^2 + 1 + y*2 let val1 = equation => (x => 3, y => 4) let exact = sin(pi / 4) let approx = evalf(exact) 12. 相等性语义 -------------------------------------------------------------------------------- - 结构相等: :code:`==` - 数学等价(仅 :code:`Expr` ): :code:`===` (由 LSR-007 [5]_ 单独定义) .. code-block:: text let a = vec[1,2,3] let b = a b is a # true let c = vec[1,2,3] c is a # false vec[1,2,3] == vec[1,2,3] # true [1,2;3,4] == [1,2;3,4] # true 13. 序列与模块系统 -------------------------------------------------------------------------------- 13.1 序列生成 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code-block:: text func square(x num) -> num { return x^2 } let nums = range(1,10) let squares = nums |> map(square) range(start int, end int) -> vector 13.2 命名空间与模块 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :code:`import` :加载模块并绑定模块对象;标准库模块导入见 [2]_。 :code:`use` :从模块导入符号到当前作用域(冲突时报错)。 .. code-block:: text import std.math import physics.quantum let val = math.sin(math.pi / 2) use std.math.{sin, cos, pi, e} use std.linalg.{det} let wave = sin(pi * x) + cos(e * x) let D = det(matrix_A) use std.constants.{G as GRAVITY} 14. 引用 -------------------------------------------------------------------------------- .. [1] :doc:`LSR-003 - Lamina C 扩展与插件规范 ` - Lamina C 扩展与插件规范 .. [2] :doc:`LSR-004 - 标准库规范 ` - 标准库规范(模块结构、数学系统、库调用约定) .. [3] :doc:`LSR-005 - 模式匹配 ` - match 规范(语法、穷尽检查、模式系统) .. [4] :doc:`LSR-006 - Lambda 规范 ` - Lambda 规范(语法、类型推导、管道交互) .. [5] :doc:`LSR-007 - 数学等价判定规范 ` - :code:`===` 数学等价规范(判定边界与化简策略) .. [6] :doc:`LSR-008 - 量纲剥离规范 ` - 量纲剥离规范( :code:`as num` 语义、边界与错误模型)