Files
endorphin-tabularium-docs/content/docs/language-design/03-questions.md
T
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

251 lines
9.3 KiB
Markdown
Raw 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.
# 03 · 值与类型
13/30 项已确认。当前推进 03-14;null 是否为对象仍未确认。其余分类中的类型、赋值和条件规则须与本章已有决定核对。
本页整理原讨论的问题、验收要求和候选方案。勾选代表讨论中已确认的规则,不代表编译器或运行时已经实现。
## 03-01 动态类型
- [x] 已确认
操作根据运行时对象的类型检查;不要求执行前通过静态类型检查。不适用的类型组合在运行时失败。
## 03-02 名字与对象绑定
- [x] 已确认
变量名绑定对象,类型属于对象;`b = a` 共享对象,重新绑定 `a` 不改变 `b`。
## 03-03 隐式转换政策
- [x] 已确认
需要转换类型时必须显式写出;不靠自动转换接受不匹配的操作数,例如 `"41" + 1` 报 `TypeError`。
## 03-04 数值类型与支持范围
- [x] 已确认
对外统一为 `Number`,覆盖整数与有理数,大小自动调整;不引入无穷大、`NaN`、虚数,正负零视为同一个数。精确性及异常运算另见下项。
## 03-05 整数性质与循环次数
- [x] 已确认
记录数值是否为整数;按次数循环要求正整数,零、负数和非整数不满足要求。具体错误形式交由 03-29 统一。
## 03-06 字符串算术操作
- [x] 已确认
确定字符串拼接、减法与重复运算的支持范围。
**已确认规则:**两个 String 可以用 + 拼接,不支持字符串减法;后续已修订为支持 String * 整数值 Number,完全等价于 duplicate,包含相同的参数检查与失败行为。
## 03-07 数值精确性
- [x] 已确认
确定有理数存储和四则运算是否始终精确,是否允许舍入。
**已确认规则:**`1 / 3` 精确保存为 `1/3`;`1/3 + 1/3` 得到 `2/3`;`1/3 * 3` 得到整数 `1`。如何显示另由 03-09 决定。
## 03-08 数值异常
- [x] 已确认
确定除零等不成立的数值运算如何失败,哪些情况交给平台模块。
**已确认规则:**`1 / 0`、`0 / 0`、`1 / (1 - 1)` 都抛出算术错误,停止本次表达式求值。具体错误名称、捕获和传播机制由【错误与异常】及 03-29 对齐。
## 03-09 数值输入与显示
- [x] 已确认
确定小数文字表示什么数、循环小数如何显示,以及显示后能否无损读回。依赖【词法与语法】。
**已确认规则:**数值按精确值解释,默认输出最简分数,分母为正;整数直接显示为整数,零显示为 `0`。
## 03-10 基本类型清单
- [x] 已确认
确定本轮内置哪些类型,以及明确不提供哪些类型。
**已确认规则:**本轮提供 `Number`、`String`、`Boolean`、空值类、`List`、`Map`、`Tuple`、`Set`、`Bytes`、函数类、类型对象所属的类。具体类名暂定。 空值类的对象地位在 03-14 被重新提出,仍待确认;不能据此宣布 null 已确定为对象。
## 03-11 字符串的值模型
- [x] 已确认
确定字符单位、Unicode 处理及索引单位;补齐空字符串等边界。
**已确认规则:**合法 Unicode 标量序列;保留原码点、不自动规范化;默认按码点计数,字素簇使用专门接口;索引从零开始、支持负索引、单个索引越界报错;普通正向切片左闭右开、越界截断、空范围返回空字符串。 创建或解码时拒绝非法编码和孤立代理项,不自动替换或丢弃;原始数据用 Bytes 保存。
## 03-12 字符串重复方法
- [x] 已确认
确定名称、次数参数、零和负数、错误行为及返回值。
**已确认规则:**`s.duplicate(n)` 返回重复后的 `String`,不修改接收者。`n` 必须是非负整数值的 `Number`;零次返回空字符串,负数、非整数及其他类型报错,不做隐式转换。
## 03-13 布尔值与条件转换
- [x] 已确认
确定布尔值是否独立于数字,以及条件位置接受布尔值还是其他值。依赖【控制流】。
**已确认规则:**`Boolean` 独立于 `Number`;条件表达式只接受 `Boolean` 对象。`true`、`false` 可以作为条件,数字、字符串、容器、空值等直接作为条件均报 `TypeError`。具体控制流语法由【控制流】对齐。
## 03-14 空值与缺失
- [ ] 待讨论
确定是否区分空值、缺失、未初始化和无返回值,以及误用时的行为。
## 03-15 复合值规则
- [ ] 待讨论
为选中的容器、元组、记录或枚举等确定成员类型限制、缺失成员及递归结构规则。
## 03-16 用户定义类型的能力
- [ ] 待讨论
确定用户能定义哪些类型,哪些能力仅供内置类型使用。依赖【对象与类型模型】。
## 03-17 类型身份与兼容性
- [ ] 待讨论
确定按名字还是结构认类型、如何处理子类型,以及哪些类型可以互相替代。
## 03-18 运行时类型查询
- [ ] 待讨论
确定如何取得类型、检查类型及检查能力;明确精确类型与子类型检查的区别。
## 03-19 显式转换接口
- [ ] 待讨论
确定转换入口、支持的转换、可能丢失信息的转换及失败行为。
## 03-20 泛型与容器类型约束
- [ ] 待讨论
决定是否支持参数化类型或带成员约束的容器;支持则规定运行时如何检查。
## 03-21 可选类型标注
- [ ] 待讨论
决定是否提供;提供则明确其用途及是否影响运行行为。
## 03-22 顶级类型与顶级类
- [ ] 待讨论
分别决定是否存在能容纳所有值的类型,以及是否存在统一祖先类。
## 03-23 可变性与共享
- [ ] 待讨论
确定哪些对象可变,以及多个名字共享对象时能观察到什么变化。
## 03-24 复制语义
- [ ] 待讨论
确定赋值之外是否提供复制、浅复制和深复制,以及循环引用如何处理。
## 03-25 相等与身份
- [ ] 待讨论
确定内容相等和同一对象如何区分,以及不同类型之间如何比较。
## 03-26 哈希与键的限制
- [ ] 待讨论
确定哪些值可作集合成员或映射键,保证相等、哈希和可变性规则一致。
## 03-27 参数与返回值的绑定
- [ ] 待讨论
确定传参、返回、重新绑定及修改对象的可见效果。依赖【函数与调用】。
## 03-28 显式引用能力
- [ ] 待讨论
决定能否直接取得并传递“变量存储单元”的引用;不支持也可完成此项。
## 03-29 类型相关错误契约
- [ ] 待讨论
统一类型不匹配、值不合法、转换失败等情况的错误分类。依赖【错误与异常】。
## 03-30 跨分类一致性验收
- [ ] 待讨论
用一组正常和失败示例核对类型、转换、对象、运算、函数与控制流规则,消除冲突和阻塞。
## 当前问题的方案与语言对照
以下沿用原讨论材料;建议和参考语言的做法均不自动成为本语言规则。
可以,**你要的空状态表示“变量位置存在,但当前没有指向对象”**。
不过,“避免回收”这里需要区分两件事:
```text
result = null
……之后……
result = calculate()
```
这是**先保留名字,之后再绑定对象**。前面还没有计算结果对象,因此没有对象需要保活。名字什么时候有效,由作用域规则决定。
如果已经有对象,情况不同:
```text
a = 某个对象
b = a
a = null
```
在采用强引用与自动回收的模型中,`b` 仍持有该对象,就不能提前回收它;如果所有有效强引用都消失,对象才可能被回收。**把变量设成 `null` 会解除它原来的引用,不会保护原对象。**具体回收机制属于【运行时与内存管理】,尚未确定。
各语言也区分“空状态”和“对象保活”:
| 语言 | 空状态怎样表达 | 对我们的启发 |
|---|---|---|
| **Python** | `None` 本身是一个对象,名字绑定到它。[对象模型](https://docs.python.org/3/reference/datamodel.html#objects-values-and-types) | 可以保持所有可绑定值都是对象的统一规则。 |
| **JS / TS** | `null` 是独立的原始值,不是对象;TS 另有静态类型约束。[JS 规范](https://tc39.es/ecma262/multipage/ecmascript-data-types-and-values.html#sec-ecmascript-language-types)、[TS 文档](https://www.typescriptlang.org/tsconfig/strictNullChecks.html) | 可以在语言层面明确允许“无对象”的值。 |
| **Go** | 指针变量可以为 `nil`,表示没有指向对象,变量本身仍存在。[语言规范](https://go.dev/ref/spec#The_zero_value) | 接近你描述的“位置存在、目标为空”。 |
| **Rust** | `Option<T>` 的 `None` 表示其中没有 `T` 值,不要求使用空指针实现。[官方说明](https://doc.rust-lang.org/std/option/) | “没有目标对象”的语义不必绑定某种内存布局。 |
这里还有一个需要明确的设计边界:
1. **空引用例外**:名字可以绑定对象,也可以持有 `null`;`null` 不属于对象。
2. **统一对象模型**:`null` 是空值类的对象,用它表示“没有业务对象”。
你说的“没有对象”,更接近 **1**。这会成为之前“所有值都是类的实例”的一个明确例外;方案 **2** 则保留那条统一规则。两者都能实现先声明、后赋值。
**你希望 `null` 本身也不是对象,采用方案 1,对吗?**
## 讨论来源
《语言设计 03:值与类型》,整理日期 2026-10-28。章节编号沿用原清单。