Files
codex-bot ef1ba88161
Verify and deploy Tabularium / verify-and-deploy (push) Waiting to run
Add language design question collection with discussion decisions and provenance
2026-10-28 14:02:12 +08:00

174 lines
8.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 06 · 表达式与运算
0/20 项已确认。当前推进 06-01;本分类尚未完成选择。
本页整理原讨论的问题、验收要求和候选方案。勾选代表讨论中已确认的规则,不代表编译器或运行时已经实现。
## 06-01 普通操作数的求值顺序
- [ ] 待讨论
明确二元运算、嵌套表达式的求值顺序,并确定是否采用一条适用于调用参数等表达式的共同规则;用有副作用的例子验收。
## 06-02 求值失败与中断
- [ ] 待讨论
明确某一步发生错误或不终止时,后续哪些步骤还会执行;说明副作用是否保留。依赖【错误处理】。
## 06-03 运算符清单与分组规则
- [ ] 待讨论
列明本轮支持的运算符、优先级、结合性,以及是否允许连续比较;用存在歧义的表达式验收。与【语法】核对。
## 06-04 数值运算的类型组合与转换
- [ ] 待讨论
确定哪些数值组合可运算、是否隐式转换、结果类型,以及不允许组合的失败方式。依赖【类型系统】。
## 06-05 算术结果的具体含义
- [ ] 待讨论
明确支持的加减乘除、余数及其他算术规则,覆盖负数、零、除零、舍入和精度。
## 06-06 溢出与特殊数值
- [ ] 待讨论
确定整数越界、浮点溢出、无穷、NaN、正负零等情况是否存在,以及相应行为。依赖【数值类型】。
## 06-07 同类型值的相等
- [ ] 待讨论
确定相等比较的含义、结果要求,以及复合值按结构还是其他方式比较;说明是否允许违反自反性等性质。
## 06-08 跨类型相等
- [ ] 待讨论
确定不同类型的值能否相等、是否转换,以及无法比较时返回假还是失败;与数值转换规则核对。
## 06-09 身份比较
- [ ] 待讨论
决定是否提供身份判断、哪些值具有身份,以及复制、共享对身份的影响。依赖【对象与类型模型】【内存与生命周期】。
## 06-10 大小比较
- [ ] 待讨论
确定可比较的类型、全序或偏序、不可比较时的行为,以及大小比较与相等的关系。
## 06-11 哈希及其约束
- [ ] 待讨论
决定哪些值可哈希,明确相等与哈希一致性的要求,以及可变值和自定义相等的影响。与【集合与容器】核对。
## 06-12 条件位置接受什么值
- [ ] 待讨论
确定条件必须为布尔值还是允许其他值,并说明转换规则和失败行为。与【控制流】【类型系统】核对。
## 06-13 逻辑运算与短路
- [ ] 待讨论
确定逻辑运算符、是否跳过右侧、结果为布尔值还是操作数,以及能否自定义这些行为。
## 06-14 位运算与移位
- [ ] 待讨论
决定是否支持;若支持,明确适用类型、位宽、负数、右移和非法移位量的行为。
## 06-15 运算扩展的声明方式
- [ ] 待讨论
决定用户能否定义或重载运算,以及通过函数、协议、类型成员或其他机制声明。依赖【类型系统】【定制协议】。
## 06-16 运算实现的选择规则
- [ ] 待讨论
若允许扩展,确定左右操作数、类型匹配、转换和候选优先级,以及歧义的处理;若不允许扩展,记录内置选择规则。
## 06-17 不支持操作时的行为
- [ ] 待讨论
明确“不支持”、运算内部出错、存在歧义的区别,以及编译期和运行期分别如何处理。依赖【类型系统】【错误处理】。
## 06-18 复合赋值与修改语义
- [ ] 待讨论
决定是否支持 `+=` 等形式;若支持,明确目标求值次数、是否原地修改、失败后的状态。依赖【变量与赋值】【对象与类型模型】。
## 06-19 常量求值与优化边界
- [ ] 待讨论
明确常量表达式和普通表达式是否遵守相同结果、错误与精度规则,以及优化必须保留哪些可观察行为。依赖【执行模型】。
## 06-20 跨分类一致性验收
- [ ] 待讨论
核对上述规则与相关分类的最终决定;通过包含副作用、混合数值、不可比较值、哈希、自定义运算和失败路径的代表性例子,解决所有冲突。
## 当前问题的方案与语言对照
以下沿用原讨论材料;建议和参考语言的做法均不自动成为本语言规则。
当前仍是 **06-01:普通操作数的求值顺序**。要决定的是:一个表达式包含多个计算步骤时,语言保证怎样的先后顺序。
例如下面的伪代码,假设各函数都会记录自己被调用了:
```text
a() + b() * c()
```
“先乘后加”决定运算分组;它并不意味着必须先调用 `b()`。我们讨论的是这些函数以及普通变量读取的先后顺序。
相关语言的对照如下。这里说的是语言规则,后面的取舍分析不代表其历史设计动机。
| 语言 | 规则与具体行为 | 对我们设计的启发与取舍 |
|---|---|---|
| **Python 3** | 普通表达式从左到右求值。上例依次调用 `a、b、c`,再完成乘法、加法。赋值另有规则:先求右侧,再处理左侧目标。[语言参考](https://docs.python.org/3/reference/expressions.html#evaluation-order) | 顺序容易预测;实现需要保留可观察行为。也提醒我们应明确赋值等特殊结构的边界。 |
| **JavaScript / TypeScript** | JS 的普通算术表达式先求左操作数,再求右操作数;上例也是 `a、b、c`。TS 对这类表达式提供静态检查,运行时遵循生成的 JS 的规则,类型标注不会建立另一套求值顺序。[ECMAScript 规范](https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-evaluatestringornumericbinaryexpression)、[TS 文档](https://www.typescriptlang.org/docs/handbook/2/basic-types.html#erased-types) | 类型检查与求值顺序可以分别设计;无论选择静态还是动态类型,都可以保证从左到右。 |
| **Rust** | 普通算术、调用参数、元组元素等规定按源码从左到右求值,上例也是 `a、b、c`。赋值和复合赋值另有专门规则。[Rust Reference](https://doc.rust-lang.org/reference/expressions.html#evaluation-order-of-operands)、[赋值规则](https://doc.rust-lang.org/reference/expressions/operator-expr.html#assignment-expressions) | 明确顺序与编译优化可以并存;需要谨慎控制特殊规则,否则使用者记忆负担会上升。 |
| **Go** | 采用部分顺序保证:函数调用、方法调用、接收操作等按词法从左到右,但并非所有普通读取都固定顺序。所以上例调用仍是 `a、b、c`,但下面的例子可能有两个结果。[Go 规范](https://go.dev/ref/spec#Order_of_evaluation) | 可以只固定部分操作的顺序,给其他求值留下自由;代价是“从左到右”的直觉不足以解释所有表达式。 |
Go 的区别可以用这个例子看出来:
```go
a := 1
f := func() int { a++; return a }
x := []int{a, f()}
```
规范允许 `x` 是 `[1, 2]` 或 `[2, 2]`:普通读取 `a` 与调用 `f()` 之间的顺序没有固定。这说明,**仅保证函数调用从左到右,比保证所有普通操作数从左到右更弱**。[Go 规范中的示例](https://go.dev/ref/spec#Order_of_evaluation)
据此,我们有三个可选方案:
- **A:普通操作数统一从左到右。** 变量读取、函数调用等都遵守;逻辑短路、赋值等结构单独明确。最容易推理。
- **B:普通操作数顺序不作保证。** 必要的先后依赖仍须遵守;带副作用的表达式可能允许多个结果,实现选择空间更大。
- **C:部分操作保证从左到右。** 类似 Go,固定调用等操作的顺序,允许其他求值顺序不确定。折中,但规范和使用都更复杂。
**我建议 A**,原因是它能为后续错误传播、重载和复合表达式提供清晰基础;不能观察到差别的优化仍可进行。错误发生后的传播规则留在 06-02,短路留在 06-13,赋值与复合赋值的顺序另行核对。
你选择 **A、B,还是 C**?
## 讨论来源
《语言设计 06:表达式与运算》,整理日期 2026-10-28。章节编号沿用原清单。