diff --git a/README.md b/README.md index 06162f4..b9cfc02 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,8 @@ tools/figures/ 独立 Python 项目,使用 drawsvg 编程制图 Pretext 教程位于 `content/docs/pretext`,包含导读与12章,来自本地 Pretext 研究成果。源码链接锁定上游研究版本;实验脚本与原始记录位于 `apps/docs/public/materials/pretext`,和正文一样经过登录验证。普通 Markdown 与 GFM 表格可用,嵌入图使用 `/figures/.svg`。不解析原始 HTML。 +语言设计问题集位于 `content/docs/language-design`,是第三个资料合集,包含总览与原编号02–14的13个分类,共271项议题。原讨论已确认26项,其余保持待讨论;来源映射和本次状态记录位于 `content/language-design-sources.json`。维护时同步章节、总览计数与来源状态;不会自动从聊天同步,也不把设计记录等同于已实现功能。 + 生产构建会生成文档路由;新增或修改文档后重新运行 build。开发模式按请求读取内容。 main 推送通过 CI 验证后自动部署;Pull Request 只验证,不部署。工作流也支持手动触发。 diff --git a/apps/docs/src/styles/globals.css b/apps/docs/src/styles/globals.css index 6feff75..9fb3fa8 100644 --- a/apps/docs/src/styles/globals.css +++ b/apps/docs/src/styles/globals.css @@ -1059,7 +1059,7 @@ button { .library-intro h1 { margin: 0 0 14px; font-size: 38px; font-weight: 600; letter-spacing: -1px; } .library-intro p { margin: 0; font-size: 16px; color: var(--muted); } .featured-section h2, .library-section h2 { font-size: 19px; font-weight: 550; margin: 0 0 22px; } -.featured-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; } +.featured-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr)); gap: 20px; } .featured-link { position: relative; border: 1px solid var(--line); border-radius: 8px; padding: 26px; } .featured-link:hover { border-color: #a4b7aa; background: #fafcfb; } .featured-link > svg:first-child { color: var(--green); margin-bottom: 18px; } diff --git a/content/catalog.json b/content/catalog.json index 286e588..439f9a2 100644 --- a/content/catalog.json +++ b/content/catalog.json @@ -5,6 +5,11 @@ "title": "Pretext 源码教程", "description": "从浏览器排版基础到缓存、换行算法与虚拟列表。" }, + { + "path": "language-design", + "title": "语言设计问题集", + "description": "13 个分类的语言设计问题、候选方案与确认记录。" + }, { "path": "", "title": "Endor 文档", @@ -39,6 +44,62 @@ "pretext/00-overview": { "description": "理解高性能文本布局的原理,沿着 12 章教程阅读源码。", "featured": true + }, + "language-design/00-overview": { + "description": "从名称与作用域到反射与表示,按 271 项议题逐步讨论语言设计。", + "featured": true + }, + "language-design/02-questions": { + "description": "语言设计讨论底稿;包含问题、验收要求和当前确认状态。", + "draft": true + }, + "language-design/03-questions": { + "description": "语言设计讨论底稿;包含问题、验收要求和当前确认状态。", + "draft": true + }, + "language-design/04-questions": { + "description": "语言设计讨论底稿;包含问题、验收要求和当前确认状态。", + "draft": true + }, + "language-design/05-questions": { + "description": "语言设计讨论底稿;包含问题、验收要求和当前确认状态。", + "draft": true + }, + "language-design/06-questions": { + "description": "语言设计讨论底稿;包含问题、验收要求和当前确认状态。", + "draft": true + }, + "language-design/07-questions": { + "description": "语言设计讨论底稿;包含问题、验收要求和当前确认状态。", + "draft": true + }, + "language-design/08-questions": { + "description": "语言设计讨论底稿;包含问题、验收要求和当前确认状态。", + "draft": true + }, + "language-design/09-questions": { + "description": "语言设计讨论底稿;包含问题、验收要求和当前确认状态。", + "draft": true + }, + "language-design/10-questions": { + "description": "语言设计讨论底稿;包含问题、验收要求和当前确认状态。", + "draft": true + }, + "language-design/11-questions": { + "description": "语言设计讨论底稿;包含问题、验收要求和当前确认状态。", + "draft": true + }, + "language-design/12-questions": { + "description": "语言设计讨论底稿;包含问题、验收要求和当前确认状态。", + "draft": true + }, + "language-design/13-questions": { + "description": "语言设计讨论底稿;包含问题、验收要求和当前确认状态。", + "draft": true + }, + "language-design/14-questions": { + "description": "语言设计讨论底稿;包含问题、验收要求和当前确认状态。", + "draft": true } } } diff --git a/content/docs/language-design/00-overview.md b/content/docs/language-design/00-overview.md new file mode 100644 index 0000000..6fb1531 --- /dev/null +++ b/content/docs/language-design/00-overview.md @@ -0,0 +1,50 @@ +# 语言设计问题集 + +从名称与作用域到反射与表示,集中维护语言设计讨论中的问题、候选方案与确认记录。 + +当前收录 **13 个分类、271 项议题,26 项已确认**。本合集是设计工作底稿,不是已经实现的语言规范。 + +## 章节目录 + +| 分类 | 议题数 | 已确认 | 当前问题 | +| --- | ---: | ---: | --- | +| [02 · 名称与作用域](/docs/language-design/02-questions) | 22 | 13 | 02-15 | +| [03 · 值与类型](/docs/language-design/03-questions) | 30 | 13 | 03-14 | +| [04 · 存储与生命周期](/docs/language-design/04-questions) | 20 | 0 | 04-01 | +| [05 · 对象与成员](/docs/language-design/05-questions) | 18 | 0 | 05-01 | +| [06 · 表达式与运算](/docs/language-design/06-questions) | 20 | 0 | 06-01 | +| [07 · 函数与调用](/docs/language-design/07-questions) | 22 | 0 | 07-01 | +| [08 · 控制流](/docs/language-design/08-questions) | 20 | 0 | 08-01 | +| [09 · 集合与访问协议](/docs/language-design/09-questions) | 22 | 0 | 09-01 | +| [10 · 错误与资源](/docs/language-design/10-questions) | 16 | 0 | 10-01 | +| [11 · 模块与程序执行](/docs/language-design/11-questions) | 22 | 0 | 11-01 | +| [12 · 并发与异步](/docs/language-design/12-questions) | 21 | 0 | 12-01 | +| [13 · 外部交互](/docs/language-design/13-questions) | 22 | 0 | 13-01 | +| [14 · 反射与表示](/docs/language-design/14-questions) | 16 | 0 | 14-01 | + +## 怎样继续讨论 + +每项保留原编号、问题范围与验收要求。只有规则、正常示例、边界情况和失败行为明确,并且已有用户确认或明确授权的默认方案时,才勾选完成。建议、语言对照和“已介绍过”均不计为已确认。明确决定不支持某项能力时,也应记录其后果。 + +已有展开的问题保留 Python、JavaScript/TypeScript、Go、Rust 等语言的对照和原始资料链接;其余议题保留问题与验收要求,后续讨论时再补充对应方案与来源。 + +复选框是 Markdown 中的维护记录。更新章节后,也要同步本页的数量、当前问题和跨分类约束;网站不会自动从聊天同步。 + +## 已有决定与待对齐事项 + +- **名称与作用域**:已确认词法作用域、普通函数局部绑定、块内 `let`、遮蔽、编译时确定赋值检查、`nonlocal`、循环中的独立 `let` 绑定和默认捕获绑定。02-11 的特殊结构作用域仍待核对;02-15 的多个闭包共享读写仍待选择。 +- **值与类型**:已确认动态类型、名字绑定对象、显式转换、精确有理数 `Number`、默认分数显示、Unicode 字符串及独立 `Boolean`;条件只接受 `Boolean`。`String * 整数值 Number` 已修订为等价于 `duplicate`,不能继续沿用早期“不支持字符串乘法”的记录。 +- **空值仍待确认**:已提出“变量位置存在、当前没有目标对象”的需求;`null` 本身是否为对象尚未得到最终确认。把引用设为 `null` 不会替原对象保活,具体回收机制仍待设计。 +- **赋值与对象模型**:04-01、05-01 的原讨论尚未完成,但 03 已记录对象绑定与基本类型按类建模的方向。后续应先核对适用范围,再决定生命周期和对象扩展规则,避免重新默认为全部未定。 +- **运算、控制流与集合**:06 的类型组合与条件、08 的真值判断、09 的文本索引应分别对齐 03 的显式转换、仅布尔条件及码点索引规则。 +- **错误机制**:03 已确认除零触发算术错误;10 的通用失败模型仍待选择。错误分类、捕获与传播必须交叉核对。 +- **执行与类型检查**:03 原讨论记录了解释执行、REPL 与动态类型的方向。名称与确定赋值仍可做执行前检查;不应把动态类型误写成“没有任何执行前检查”。其他章节的“静态或运行时待定”应按具体检查对象重新核对。 + +跨分类事项保持未完成,直到相关分类明确对齐。本次整理不据此替用户选择新的规则。 + +## 来源与维护范围 + +本合集依据用户指定的“语言设计 02”至“语言设计 14”聊天整理,截至 2026-10-28。章节保留原编号,本次没有提供 01 分类的对应语言设计聊天,因此不补造该章。附带的《Chromium 主线 01:导航与文档提交》属于另一主题,未并入。 + +各章末尾标明原讨论标题;仓库的 `content/language-design-sources.json` 记录对应聊天标识,便于后续追溯。它是本次整理的来源清单,不是自动同步配置。 + diff --git a/content/docs/language-design/02-questions.md b/content/docs/language-design/02-questions.md new file mode 100644 index 0000000..026d0aa --- /dev/null +++ b/content/docs/language-design/02-questions.md @@ -0,0 +1,196 @@ +# 02 · 名称与作用域 + +13/22 项已确认。当前推进 02-15;02-11 的特殊结构作用域仍需核对。 + +本页整理原讨论的问题、验收要求和候选方案。勾选代表讨论中已确认的规则,不代表编译器或运行时已经实现。 + +## 02-01 词法作用域 + +- [x] 已确认 + +名称按定义位置的代码嵌套关系查找;调用者的局部变量不会参与被调用函数的名称查找。 + +## 02-02 普通变量的基本作用范围 + +- [x] 已确认 + +不需要声明关键词;函数内普通变量采用 Python 式作用范围,普通 `if`、`for` 块不限制它。块内赋值后,块外可以使用,前提是该赋值确实发生。 + +## 02-03 `let` 临时绑定 + +- [x] 已确认 + +`let` 声明的变量限定在所属块内;后续赋值仍操作该临时绑定,不扩大作用域;不提供 `var`。 + +## 02-04 内层遮蔽外层 + +- [x] 已确认 + +内层 `let` 可以与外层变量同名。块内读写内层绑定,退出后恢复访问外层绑定,外层值不受这些修改影响。 + +## 02-05 同层重复 `let` + +- [x] 已确认 + +同一作用域重复声明同名 `let` 报错;修改已有变量使用普通赋值。 + +## 02-06 `let` 声明前的直接使用 + +- [x] 已确认 + +整个块中的同名直接读写都认定为该临时绑定;声明前使用在编译检查阶段报错,不会转而访问外层同名变量。 + +## 02-07 分支与未初始化读取 + +- [x] 已确认 + +确定不能保证读取前已赋值时,编译报错还是运行时报错;覆盖条件分支、可能执行零次的循环和提前退出。 + +**已确认规则:**采用编译时的确定赋值检查。每条能够到达读取位置的路径都必须先赋值;编译器无法证明这一点,就报错。 + +## 02-08 普通变量的声明前查找 + +- [x] 已确认 + +确定函数后面出现普通赋值时,前面的同名读取算本地未初始化,还是可以访问外层绑定。 + +**已确认规则:**局部归属按整个函数确定,赋值前读取不能回退到外层同名变量。 + +## 02-09 同层名称冲突 + +- [x] 已确认 + +明确参数、普通变量、`let` 之间哪些组合属于赋值、哪些属于重复声明或冲突。 + +**已确认规则:**参数后的普通赋值修改参数绑定;参数与函数体同层 let 同名、同层重复 let、重复参数名均编译报错;更内层 let 可以遮蔽;let 之前的同名赋值属于声明前访问,编译报错。 + +## 02-10 内层函数修改外层绑定 + +- [x] 已确认 + +明确普通赋值默认修改哪一层,是否需要专门语法才能修改外层变量。 + +**已确认规则:**普通赋值默认建立或修改当前函数的局部绑定;通过 `nonlocal` 显式指定外层函数中已有的绑定。 + +## 02-11 各语法结构的作用域边界 + +- [ ] 待讨论 + +列清函数、独立块、循环及其他受支持结构各自如何引入绑定;未决定是否支持的结构标注依赖。依赖:**语法设计**。 + +## 02-12 循环绑定 + +- [x] 已确认 + +确定循环变量和循环体中的 `let` 是每轮建立新绑定,还是多轮复用;说明闭包捕获后的结果。 + +**已确认规则:**每次进入循环体,创建这一轮自己的 `let` 绑定;普通变量继续复用所属函数中的绑定。循环外不能访问循环体内的 `let`。若支持循环头的 `let`,也采用每轮独立绑定的原则。 + +## 02-13 声明与初始化顺序 + +- [x] 已确认 + +明确 `let` 能否不带初值、初始化表达式中的同名引用如何处理,以及受支持的复合声明按什么顺序建立绑定。依赖:**语法设计**。 + +**已确认规则:**允许先声明后赋值;初始化前读取自身报错;多目标声明或赋值先求完整右侧,再绑定目标。具体复合语法由语法设计对齐。 + +## 02-14 闭包捕获什么 + +- [x] 已确认 + +确定默认捕获绑定还是当时的值,以及是否提供显式选择。 + +**已确认规则:**默认捕获绑定;外层重新赋值后,闭包读到新值。需要快照时手动建立独立绑定,不自动深拷贝对象。 + +## 02-15 闭包修改与共享 + +- [ ] 待讨论 + +确定多个闭包是否共享同一外层绑定、哪些修改允许、哪些情况报错。依赖:**可变性规则**。 + +## 02-16 逃逸闭包的绑定存续 + +- [ ] 待讨论 + +确定外层函数返回或代码块退出后,闭包仍可访问什么,以及如何保证访问有效。依赖:**运行时实现、资源管理**。 + +## 02-17 完整名称查找顺序 + +- [ ] 待讨论 + +明确函数外层、模块、内置名称的查找顺序,以及类成员是否参与裸名称查找。依赖:**模块系统、对象与类型模型、内置库设计**。 + +## 02-18 模块可见性 + +- [ ] 待讨论 + +明确默认私有还是公开、如何导出,以及访问不可见名称时的错误。依赖:**模块系统**。 + +## 02-19 导入名称的绑定与冲突 + +- [ ] 待讨论 + +明确导入名能否重新赋值、别名和重名如何处理、导入后观察到的是哪个绑定。依赖:**模块系统**。 + +## 02-20 跨模块初始化 + +- [ ] 待讨论 + +明确循环导入或模块尚未初始化时,读取其名称如何处理。依赖:**模块系统、执行模型**。 + +## 02-21 类型名与值名的关系 + +- [ ] 待讨论 + +确定是否共享命名空间、同名是否冲突、名称如何区分解析。依赖:**类型系统**。 + +## 02-22 最终一致性验收 + +- [ ] 待讨论 + +用一组正常与错误示例交叉检查上述规则,解决跨分类冲突,形成最终规则摘要。 + +## 当前问题的方案与语言对照 + +以下沿用原讨论材料;建议和参考语言的做法均不自动成为本语言规则。 + +接下来是 **02-15:多个闭包能否共同读写同一个绑定**。 + +```text +fn example() { + count = 0 + + fn increase() { + nonlocal count + count = count + 1 + } + + fn read() { + return count + } + + increase() + print(read()) // 如果允许共享,输出 1 +} +``` + +各语言的相关规则: + +| 语言 | 做法 | 收益与代价 | +|---|---|---| +| **Python** | 多个闭包可以共享绑定;修改外层函数绑定需要 `nonlocal` | 共享状态方便,修改也有明确标记;多个函数的行为会相互影响。[官方说明](https://docs.python.org/3/faq/programming.html#why-am-i-getting-an-unboundlocalerror-when-the-variable-has-a-value) | +| **JS / TS** | 可以共享并修改同一绑定,不需要 `nonlocal`;TS 保持 JS 的运行语义 | 写法直接,读代码时需要留意哪些闭包会修改变量。[官方手册](https://www.typescriptlang.org/docs/handbook/variable-declarations.html) | +| **Go** | 外层函数与闭包共享变量,允许修改 | 共享直接;并发执行时需要另行协调访问。[规范](https://go.dev/ref/spec#Function_literals) | +| **Rust** | 借用捕获受访问限制约束;相互冲突的可变借用和只读借用不能同时存续。共享可变状态需要合适的显式机制 | 编译器能限制冲突访问,但需要更多所有权与借用规则。[官方说明](https://doc.rust-lang.org/book/ch13-01-closures.html#capturing-references-or-moving-ownership) | + +我们有两个主要方向: + +1. **允许多个闭包共享读写**:上面例子合法,输出 `1`;修改仍要求 `nonlocal`。 +2. **限制共享可变捕获**:某些同时持有读写访问的闭包组合被拒绝;具体限制需要与所有权模型一起设计。 + +我推荐 **1**,与前四种语言的方向一致,也能延续已经采用的 `nonlocal`。这里先决定单线程中的共享行为;并发访问规则属于并发模型。 + +## 讨论来源 + +《语言设计 02:名称与作用域》,整理日期 2026-10-28。章节编号沿用原清单。 + diff --git a/content/docs/language-design/03-questions.md b/content/docs/language-design/03-questions.md new file mode 100644 index 0000000..d429434 --- /dev/null +++ b/content/docs/language-design/03-questions.md @@ -0,0 +1,250 @@ +# 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` 的 `None` 表示其中没有 `T` 值,不要求使用空指针实现。[官方说明](https://doc.rust-lang.org/std/option/) | “没有目标对象”的语义不必绑定某种内存布局。 | + +这里还有一个需要明确的设计边界: + +1. **空引用例外**:名字可以绑定对象,也可以持有 `null`;`null` 不属于对象。 +2. **统一对象模型**:`null` 是空值类的对象,用它表示“没有业务对象”。 + +你说的“没有对象”,更接近 **1**。这会成为之前“所有值都是类的实例”的一个明确例外;方案 **2** 则保留那条统一规则。两者都能实现先声明、后赋值。 + +**你希望 `null` 本身也不是对象,采用方案 1,对吗?** + +## 讨论来源 + +《语言设计 03:值与类型》,整理日期 2026-10-28。章节编号沿用原清单。 + diff --git a/content/docs/language-design/04-questions.md b/content/docs/language-design/04-questions.md new file mode 100644 index 0000000..7d7237f --- /dev/null +++ b/content/docs/language-design/04-questions.md @@ -0,0 +1,161 @@ +# 04 · 存储与生命周期 + +0/20 项已确认。当前推进 04-01;本分类尚未完成选择。 + +本页整理原讨论的问题、验收要求和候选方案。勾选代表讨论中已确认的规则,不代表编译器或运行时已经实现。 + +## 04-01 赋值的默认语义 + +- [ ] 待讨论 + +明确赋值默认是独立值、共享还是移动;是否按值的类别区分,以及如何识别这种区别。 + +## 04-02 创建、身份与存储位置 + +- [ ] 待讨论 + +明确何时产生新实例、身份是否可观察,以及存储位置和地址是否属于语言保证。依赖:对象与类型模型。 + +## 04-03 初始化流程 + +- [ ] 待讨论 + +明确初始化顺序、必需字段、默认值和“可正常使用”的判定条件。 + +## 04-04 初始化期间的访问与逃逸 + +- [ ] 待讨论 + +明确未完成初始化的值能否被读取、调用、共享或捕获,以及违规行为。 + +## 04-05 初始化失败 + +- [ ] 待讨论 + +明确失败如何传播、已初始化部分如何清理,以及外部可观察状态的保证。 + +## 04-06 别名与修改权限 + +- [ ] 待讨论 + +明确多个引用能否同时存在、谁能修改,以及修改对其他持有者是否可见。 + +## 04-07 复制规则 + +- [ ] 待讨论 + +明确哪些值可复制、浅复制与深复制的含义、内部共享关系及复制失败行为。 + +## 04-08 移动规则 + +- [ ] 待讨论 + +明确是否支持移动、何时发生、源值之后能做什么,以及禁止移动的情况。 + +## 04-09 跨函数与闭包传递 + +- [ ] 待讨论 + +明确传参、返回值、闭包捕获沿用哪些生命周期规则,局部值逃逸如何处理。依赖:函数与闭包相关规则。 + +## 04-10 所有权与借用 + +- [ ] 待讨论 + +明确是否存在所有者、借用及其期限;哪些约束由静态检查或运行时检查保证。依赖:类型系统。 + +## 04-11 引用失效与悬空访问 + +- [ ] 待讨论 + +明确销毁、容器变化、存储迁移等情况下引用何时失效,以及失效访问的处理。 + +## 04-12 自动回收机制 + +- [ ] 待讨论 + +明确采用作用域释放、引用计数、追踪式 GC 或混合机制,并区分语言保证与实现自由。 + +## 04-13 循环引用与弱引用 + +- [ ] 待讨论 + +明确循环如何处理,是否提供弱引用,以及弱引用失效后的访问结果。 + +## 04-14 销毁时机与顺序 + +- [ ] 待讨论 + +明确销毁是否及时、顺序是否保证,以及正常退出和提前退出时的行为。 + +## 04-15 清理中的异常行为 + +- [ ] 待讨论 + +明确清理失败、重复清理、清理期间重入,以及重新发布待销毁值的处理规则。 + +## 04-16 非内存资源 + +- [ ] 待讨论 + +明确文件、锁等资源如何及时释放,是否支持显式关闭或作用域管理,以及关闭后操作的结果。 + +## 04-17 用户自定义生命周期操作 + +- [ ] 待讨论 + +明确哪些创建、复制、移动、清理操作允许定制,其触发时机与限制。依赖:定制协议。 + +## 04-18 分配失败与手动存储能力 + +- [ ] 待讨论 + +明确内存不足如何表现,以及是否暴露手动分配、释放或分配器选择;不支持也须明确。 + +## 04-19 并发、异步与外部接口边界 + +- [ ] 待讨论 + +明确跨执行单元共享或转移、任务取消、外部代码持有值时的生命周期契约;不支持的能力明确排除。依赖:相应并发及外部接口规则。 + +## 04-20 跨分类一致性验收 + +- [ ] 待讨论 + +用创建、共享、传递、失败、退出的完整例子检查已定规则;解决与类型、对象、协议和运行时规则的冲突。 + +## 当前问题的方案与语言对照 + +以下沿用原讨论材料;建议和参考语言的做法均不自动成为本语言规则。 + +当前仍是 **04-01:`b = a` 默认意味着什么?** 重点看两个问题:修改 `b` 是否影响 `a`,赋值后还能否使用 `a`。 + +- **Python:赋值建立绑定,不复制对象。** + `a = [1]; b = a; b.append(2)` 后,`a` 也是 `[1, 2]`。但给 `b` 重新赋值不会改变 `a` 的绑定。共享很方便,代价是可变对象的修改会沿别名传播。对我们的启发是:必须分清“修改同一个值”和“变量改为指向另一个值”。这是 Python 的语义,不依赖 CPython 的引用计数实现。[官方说明](https://docs.python.org/3/library/copy.html) + +- **JS:对象赋值保留同一对象;TS 沿用这一运行时行为。** + `const a = {n: 1}; const b = a; b.n = 2` 后,`a.n` 为 `2`。`const` 限制重新赋值,不会冻结对象;数字等原始值则没有可共享修改的内部状态。TS 的类型标注不会让赋值自动复制对象。好处是对象共享直接,代价是静态类型本身不消除别名影响。启发是:绑定是否可改、值是否可变、是否共享,需要分别规定。[JS 规范](https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-assignment-operators-runtime-semantics-evaluation)、[TS 文档](https://www.typescriptlang.org/docs/handbook/2/basic-types.html#erased-types) + +- **Go:复制赋给变量的值,但不递归复制它引用的数据。** + `a := [1]int{1}; b := a; b[0] = 2` 后,`a[0]` 仍为 `1`;换成切片 `a := []int{1}`,同样操作后 `a[0]` 为 `2`,因为复制的切片描述信息仍引用同一底层数组。好处是支持直接的数据复制,也能方便共享;代价是必须理解类型内部是否含引用。启发是:**“赋值复制值”不保证整份数据相互独立。** [Go 规范](https://go.dev/ref/spec#Assignment_statements) + +- **Rust:赋值根据类型发生复制或移动。** + `let a = 1; let b = a;` 后仍可读 `a`,因为整数实现了 `Copy`;`let a = String::from("hi"); let b = a;` 后再读取 `a` 会被编译器拒绝。好处是无需隐式复制字符串,也能明确资源归属;代价是使用者需要理解移动、借用和复制能力。启发是:按类型区分可行,但需要类型系统支撑;“放在栈上还是堆上”并非判断复制或移动的规则。[Rust 官方教程](https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html) + +回到我们的待选方案: + +| 方案 | 普通可变数据的 `b = a` | +|---|---| +| **A:默认独立值** | 修改 `b` 不影响 `a`;需要明确独立性覆盖到哪一层。 | +| **B:默认共享** | 修改共享内容会影响 `a`;需要独立副本时显式复制。 | +| **C:默认移动** | 转移使用资格;之后不能继续读取原来的 `a`。 | +| **D:按类别区分** | 为普通数据、共享引用、唯一资源分别规定行为;类别必须可识别。 | + +**我的建议是先从 A 或 B 确定普通可变数据的使用体验**,再在复制、移动任务中检查其他类别是否需要不同规则。这样能先明确用户可观察的行为,不必提前决定完整类型系统或回收机制。这只是推进建议,尚未替你选择。 + +对于普通可变记录或序列,你更希望默认 **A:各自独立**,还是 **B:共享修改**?如果你希望所有权成为语言的基础,也可以直接选 C 或 D。 + +## 讨论来源 + +《语言设计 04:存储与生命周期》,整理日期 2026-10-28。章节编号沿用原清单。 + diff --git a/content/docs/language-design/05-questions.md b/content/docs/language-design/05-questions.md new file mode 100644 index 0000000..0fe6a02 --- /dev/null +++ b/content/docs/language-design/05-questions.md @@ -0,0 +1,144 @@ +# 05 · 对象与成员 + +0/18 项已确认。当前推进 05-01;本分类尚未完成选择。 + +本页整理原讨论的问题、验收要求和候选方案。勾选代表讨论中已确认的规则,不代表编译器或运行时已经实现。 + +## 05-01 对象的基本模型 + +- [ ] 待讨论 + +完成标准:确定对象以记录、类实例、原型委托或明确的组合模型为基础;说明对象怎样获得数据和行为,是否必须存在类。 + +## 05-02 成员种类与命名空间 + +- [ ] 待讨论 + +完成标准:确定支持哪些成员种类;明确字段、方法、计算属性等能否同名,同名时如何处理。 + +## 05-03 成员集合与结构变化 + +- [ ] 待讨论 + +完成标准:确定成员是否预先声明,能否在运行时增加、删除或替换;说明非法变更的行为。 + +## 05-04 字段状态与可写性 + +- [ ] 待讨论 + +完成标准:确定字段是否有默认值、能否未初始化、如何表达只读;说明读取未初始化字段、非法赋值的行为。值与引用的具体规则依赖【类型系统/语言语义】。 + +## 05-05 方法接收者与方法取出 + +- [ ] 待讨论 + +完成标准:确定接收者如何传入;说明 `f = p.move` 后调用 `f()` 的含义,以及接收者不匹配时的行为。 + +## 05-06 计算属性与访问器 + +- [ ] 待讨论 + +完成标准:决定是否支持 getter、setter;若支持,明确读写触发规则、只读属性赋值及访问器递归的处理。 + +## 05-07 成员查找与缺失成员 + +- [ ] 待讨论 + +完成标准:确定查找顺序、遮蔽规则,以及成员不存在时是报错、返回特殊结果还是允许自定义处理。错误的发现时机依赖【类型系统】。 + +## 05-08 成员可见性与封装 + +- [ ] 待讨论 + +完成标准:确定公开、私有等访问范围及默认值;说明跨对象、模块、继承关系中的访问边界和失败行为。 + +## 05-09 对象创建与初始化 + +- [ ] 待讨论 + +完成标准:确定创建入口、初始化顺序、必填字段要求;说明初始化失败及初始化期间访问对象的规则。资源释放交由相关【运行时实现/语言语义】议题处理。 + +## 05-10 继承与委托关系 + +- [ ] 待讨论 + +完成标准:决定支持哪些关系、是否允许多个来源及关系变更;说明循环和非法关系的处理。是否形成子类型关系依赖【类型系统】。 + +## 05-11 组合与成员转发 + +- [ ] 待讨论 + +完成标准:确定组合对象的成员必须显式访问,还是支持自动转发;若支持转发,明确冲突、接收者和可见性规则。 + +## 05-12 覆盖与冲突约束 + +- [ ] 待讨论 + +完成标准:确定是否允许覆盖、是否要求显式标记、能否禁止覆盖;明确多个来源提供同名成员时的处理。签名兼容依赖【类型系统】。 + +## 05-13 方法分派 + +- [ ] 待讨论 + +完成标准:确定调用实现由什么决定,例如接收者或多个参数;说明重载候选冲突、无匹配实现的行为。依赖【类型系统】的部分单独标记。 + +## 05-14 调用上层或指定来源的实现 + +- [ ] 待讨论 + +完成标准:决定是否提供 `super` 或类似能力;若支持,明确查找起点及实际接收者。若不支持相关对象关系,明确其后果后可关闭此项。 + +## 05-15 类型级成员与共享状态 + +- [ ] 待讨论 + +完成标准:决定是否存在类/类型级方法和字段;明确访问方式、共享范围,以及它们与实例成员的关系。 + +## 05-16 外部扩展与行为替换 + +- [ ] 待讨论 + +完成标准:决定能否在定义之外添加方法、扩展成员或替换既有行为;明确作用范围、冲突和已有对象受到的影响。 + +## 05-17 公共基础接口、反射与内部字段边界 + +- [ ] 待讨论 + +完成标准:决定是否需要共同顶级类或公共基础协议;明确哪些成员信息可以检查,哪些运行时元数据不可作为普通成员访问。依赖【定制协议/运行时实现/内置与标准库】。 + +## 05-18 跨分类一致性验收 + +- [ ] 待讨论 + +完成标准:用一组贯穿示例检查创建、读写、方法调用、封装和行为复用;核对相关分类的已定规则,解决冲突及阻塞依赖。 + +## 当前问题的方案与语言对照 + +以下沿用原讨论材料;建议和参考语言的做法均不自动成为本语言规则。 + +**05-01 当前要决定的是:对象的数据与行为,主要通过什么机制组织?** 这里先不决定继承、动态增删成员或类型检查。 + +下面是官方文档中的语言机制;“好处与代价”是供我们判断的取舍分析。 + +| 语言 | 规则与具体行为 | 好处、代价及对我们的启发 | +|---|---|---| +| **Python** | 用户通常通过类定义实例行为。例如类定义 `move(self, dx, dy)`,调用 `p.move(3, 4)` 时自动传入 `p`。类本身也是对象。[官方文档](https://docs.python.org/3/tutorial/classes.html) | 数据与行为容易集中组织;同时需要解释实例、类、方法绑定等关系。启发:选择类模型,仍需逐项决定这些规则,不能把 Python 的整套机制一并带入。 | +| **JS** | 可以直接创建对象,也可以通过原型共享行为。例如 `p = Object.create(proto)` 后,`p.move()` 可以找到 `proto` 上的方法。`class` 也建立在原型机制之上,普通实例方法通常位于原型上。[ECMAScript 规范](https://tc39.es/ecma262/multipage/overview.html#sec-objects) | 对象创建和行为共享灵活;查找涉及自身成员与原型链,需要处理遮蔽和共享成员变化。启发:类语法与底层对象模型是两个决定。 | +| **TS** | 在 JS 之上提供静态类型检查。例如 `const p: {x: number; y: number} = {x: 1, y: 2}` 不需要定义类。普通对象类型主要按结构检查;运行时对象仍遵循 JS 语义。[官方文档](https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes.html) | 可以描述“需要哪些成员”,而不要求对象来自同一个类;但这种类型描述本身不提供运行时成员验证。启发:对象如何构成,与类型如何判断兼容,应分开决定。 | +| **Go** | 结构体定义字段,方法单独声明并关联到接收者类型。例如为 `Point` 声明接收者为 `*Point` 的 `Move` 方法,然后调用 `p.Move(3, 4)`。方法不是任意对象上随手添加的函数属性,接收者基础类型必须定义在同一包内。[语言规范](https://go.dev/ref/spec#Method_declarations) | 无须类也能组织数据与方法;扩展方法受到明确边界约束。启发:我们此前的 A 方案还应包含“记录/结构体+关联方法”这一变体,不能只考虑独立函数。 | +| **Rust** | `struct Point` 定义数据,`impl Point` 定义关联方法;例如 `move_by(&mut self, …)` 可修改接收者。没有传统的结构体继承,行为抽象还可通过 trait 表达。[方法文档](https://doc.rust-lang.org/book/ch05-03-method-syntax.html)、[继承与多态说明](https://doc.rust-lang.org/book/ch18-01-what-is-oo.html) | 数据、关联方法和行为抽象可以分别组织;需要明确它们之间的规则。启发:方法、封装和多态都不必以类继承为前提。所有权与借用属于其他分类,不随此方案自动引入。 | + +因此,仍保留三个主要方向,并把 A 说明得更完整: + +- **A.记录/结构体为基础**:数据由记录或结构体表达;行为可以是独立函数,也可以有明确关联的方法。选 A 后,再明确这两种组织方式的关系。 +- **B.类与实例为基础**:类集中描述实例的数据与行为。是否继承、能否动态扩展,继续按后续任务决定。 +- **C.对象与原型委托为基础**:对象可以直接构造,通过其他对象共享行为;必须明确委托查找规则。 + +**如果优先考虑基础机制较少、数据与行为关系显式,我建议从 A 中的“结构体+关联方法”开始。** 它能提供 `p.move(...)` 的使用方式,又不必同时引入类继承或原型链;代价是动态对象扩展需要另外设计。这只是建议,尚未定案。 + +你更倾向 **A、B,还是 C**?如果选 A,我们接着比较“独立函数为主”与“关联方法为主”。 + +## 讨论来源 + +《语言设计 05:对象与成员》,整理日期 2026-10-28。章节编号沿用原清单。 + diff --git a/content/docs/language-design/06-questions.md b/content/docs/language-design/06-questions.md new file mode 100644 index 0000000..c5f88ee --- /dev/null +++ b/content/docs/language-design/06-questions.md @@ -0,0 +1,173 @@ +# 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。章节编号沿用原清单。 + diff --git a/content/docs/language-design/07-questions.md b/content/docs/language-design/07-questions.md new file mode 100644 index 0000000..01dd517 --- /dev/null +++ b/content/docs/language-design/07-questions.md @@ -0,0 +1,182 @@ +# 07 · 函数与调用 + +0/22 项已确认。当前推进 07-01;本分类尚未完成选择。 + +本页整理原讨论的问题、验收要求和候选方案。勾选代表讨论中已确认的规则,不代表编译器或运行时已经实现。 + +## 07-01 函数作为值【进行中】 + +- [ ] 待讨论 + +明确能否赋值、存入数据、作为参数和返回结果,以及受限情形。 + +## 07-02 函数定义与创建 + +- [ ] 待讨论 + +明确具名函数、匿名函数是否支持;定义何时创建函数、何时可见,重复定义怎样处理。 + +## 07-03 可调用目标 + +- [ ] 待讨论 + +明确哪些值可以调用,调用非函数如何失败;方法、可调用对象若存在,明确接入边界。依赖:**对象与类型模型**。 + +## 07-04 调用的求值策略与顺序 + +- [ ] 待讨论 + +明确实参是立即求值还是延迟求值,调用目标与实参的求值顺序,以及求值中断后的行为。 + +## 07-05 参数传递与修改 + +- [ ] 待讨论 + +明确形参赋值、修改实参所指数据分别有什么效果;是否支持引用、借用或其他传递方式。依赖:**变量与内存模型、类型系统**。 + +## 07-06 位置参数 + +- [ ] 待讨论 + +明确按什么顺序绑定,是否支持仅限位置的参数;数量不足或过多怎样处理。 + +## 07-07 命名参数 + +- [ ] 待讨论 + +明确是否支持、参数名是否属于公开接口、与位置参数如何混用,以及未知名称与重复绑定的处理。 + +## 07-08 默认参数 + +- [ ] 待讨论 + +明确求值时机、可访问的名字、默认值之间的依赖、可变默认值的共享行为,以及省略与显式传空值的区别。 + +## 07-09 可变参数与展开 + +- [ ] 待讨论 + +明确是否支持剩余位置参数、剩余命名参数及调用展开;规定收集形式、顺序、重复名称与非法展开。 + +## 07-10 绑定失败的统一规则 + +- [ ] 待讨论 + +明确绑定失败何时发现、是否执行函数体、此前哪些表达式可能已执行,以及错误如何报告。依赖:**错误处理**。 + +## 07-11 返回与无结果 + +- [ ] 待讨论 + +明确显式返回、执行到末尾、无结果与空值、多结果及接收数量不符的行为。 + +## 07-12 递归与名字绑定 + +- [ ] 待讨论 + +明确自递归、相互递归、局部递归函数是否支持,以及重绑定函数名后递归调用指向什么。依赖:**作用域与模块**。 + +## 07-13 尾调用与调用深度 + +- [ ] 待讨论 + +明确是否保证尾调用、哪些位置算尾位置,以及调用深度耗尽怎样失败。依赖:**控制流与运行时**。 + +## 07-14 闭包的名字解析 + +- [ ] 待讨论 + +明确是否支持访问外层局部名字,采用词法作用域还是其他规则,以及遮蔽和未绑定名字的行为。依赖:**作用域**。 + +## 07-15 闭包捕获与共享状态 + +- [ ] 待讨论 + +明确捕获值还是变量、自动还是显式捕获,以及多个闭包、循环变量与外部修改之间的关系。依赖:**变量与内存模型**。 + +## 07-16 闭包逃逸与生命周期 + +- [ ] 待讨论 + +明确闭包能否比创建它的调用活得更久,捕获的资源如何保持有效,不能逃逸时如何拒绝。依赖:**资源管理与类型系统**。 + +## 07-17 函数的调用接口 + +- [ ] 待讨论 + +明确函数签名包含哪些信息、怎样检查兼容性;重载或泛型若存在,明确调用选择的接口。依赖:**类型系统**。 + +## 07-18 函数身份与比较 + +- [ ] 待讨论 + +明确函数是否可比较、复制后是否保持身份、重复创建的闭包有什么关系,以及能否作为键。依赖:**值与相等性模型**。 + +## 07-19 非普通控制流的调用边界 + +- [ ] 待讨论 + +明确异常、异步、生成器等若被采用,对调用与返回产生什么影响;只规定函数侧接口。依赖:**错误处理、并发与控制流**。 + +## 07-20 内置函数与外部函数 + +- [ ] 待讨论 + +明确它们是否遵守同样的参数、返回和错误规则,以及无法兼容时如何声明差异。依赖:**内置与标准库、外部互操作**。 + +## 07-21 语言调用语义与底层约定 + +- [ ] 待讨论 + +明确哪些行为属于语言保证,哪些由实现决定;外部调用需要哪些额外约定,避免把栈、寄存器布局误当语言规则。 + +## 07-22 跨分类一致性验收 + +- [ ] 待讨论 + +用代表性程序核对上述规则,并解决与其他分类的冲突;没有未解决的阻塞后完成。 + +## 当前问题的方案与语言对照 + +以下沿用原讨论材料;建议和参考语言的做法均不自动成为本语言规则。 + +当前仍是 **07-01:函数能否作为值**,即能否保存、传参、返回,以及通过变量调用。闭包捕获规则仍留在后续任务。 + +### 五种语言怎样做 + +下面的例子都假定已经定义了一个“输入整数、返回整数”的 `increment` 函数。取舍是针对我们设计的分析,不代表这些语言的历史设计动机。 + +| 语言 | 规则与具体行为 | 好处、代价及对我们的启发 | +|---|---|---| +| **Python** | 函数是对象。`f = increment` 保存函数,`f(3)` 调用它;也能放入列表、传参和返回。[官方教程](https://docs.python.org/3/tutorial/controlflow.html#defining-functions) | 行为组合直接;单靠语言运行时的动态检查,部分不合法调用到执行时才发现。**支持函数值,不要求我们采用动态类型或 Python 的对象模型。** | +| **JS** | 函数是可调用的对象。例如 `const f = increment; f(3)`,也能作为参数和结果。[ECMAScript 规范](https://tc39.es/ecma262/multipage/ecmascript-data-types-and-values.html#sec-object-type) | 回调与组合方便;接口的正确使用需要额外约束。**函数具有对象属性,是可单独选择的能力,不必随函数值一起引入。** | +| **TS** | 延续 JS 的函数值行为,并增加静态函数类型,例如 `const f: (x: number) => number = increment`。类型标注被擦除,实际执行的是 JS,不会自动获得运行时参数校验。[函数类型](https://www.typescriptlang.org/docs/handbook/2/functions.html)、[类型擦除](https://www.typescriptlang.org/docs/handbook/2/basic-types.html#erased-types) | 能提前检查许多接口错误;需要设计类型兼容规则,且静态检查不能代替外部输入验证。**函数值能力和检查时机可以分开决定。** | +| **Go** | 支持有静态类型的函数值,例如 `var f func(int) int = increment`,随后 `f(3)`;函数也可传参、返回。函数类型变量的零值为 `nil`。[Go 规范](https://go.dev/ref/spec#Function_types) | 调用接口明确;需要处理空函数值等边界。**可以支持函数值,同时保留较直接的签名模型;我们不必继承 `nil`。** | +| **Rust** | 支持保存、传递和返回函数相关的值,但区分函数项、函数指针和闭包。例如 `let f: fn(i32) -> i32 = increment;`。捕获环境的闭包不能直接当作普通 `fn` 指针,通常通过 `Fn` 等接口使用。[Rust 官方书](https://doc.rust-lang.org/book/ch20-04-advanced-functions-and-closures.html)、[函数指针规则](https://doc.rust-lang.org/reference/types/function-pointer.html) | 能明确表达不同调用能力;类型与接口规则更多。**一等函数不要求所有可调用值具有同一种类型或底层表示。** | + +这些语言都支持广泛的函数值能力,区别主要在类型、对象能力和环境捕获。**Rust 的类型区分并不意味着它只支持我们下面的 B。** + +### 我们当前的三个选项 + +- **A:函数只作为调用目标。** 可以直接调用,不能作为普通数据保存、传递或返回。规则较少,但通用回调需要其他机制。 +- **B:支持受限的函数引用。** 只开放明确的一部分能力,例如仅允许引用静态定义的函数。适合有具体限制目标的语言,需要说明每条限制的理由。 +- **C:函数是一等值。** 允许保存、传参和返回,遵守一般的类型与生命周期规则。随后分别决定匿名函数、闭包和函数类型。 + +**我仍建议 C**:它让排序比较器、事件回调、可替换的处理步骤等接口容易表达,同时保留后续设计空间。 + +选择 C 后,下面的基础行为应成立: + +```text +chosen = increment // 保存,不执行 +apply(chosen, 3) // apply 内部调用 chosen,得到 4 +return increment // 可以返回已有函数 +``` + +调用非函数应被拒绝;拒绝发生在静态检查还是运行时,依赖类型系统。返回捕获局部变量的函数是否允许,仍待闭包任务决定。 + +**你选择 A、B,还是 C?** + +## 讨论来源 + +《语言设计 07:函数与调用》,整理日期 2026-10-28。章节编号沿用原清单。 + diff --git a/content/docs/language-design/08-questions.md b/content/docs/language-design/08-questions.md new file mode 100644 index 0000000..a55f751 --- /dev/null +++ b/content/docs/language-design/08-questions.md @@ -0,0 +1,157 @@ +# 08 · 控制流 + +0/20 项已确认。当前推进 08-01;本分类尚未完成选择。 + +本页整理原讨论的问题、验收要求和候选方案。勾选代表讨论中已确认的规则,不代表编译器或运行时已经实现。 + +## 08-01 控制结构与值的关系 + +- [ ] 待讨论 + +明确条件、匹配、循环中哪些能作为表达式,以及结果能否被忽略;给出允许和不允许的使用位置。 + +## 08-02 条件分支的完整规则 + +- [ ] 待讨论 + +明确分支写法、结果来源、缺少 `else` 的行为,以及不同出口如何形成结果。结果兼容性依赖【类型系统】。 + +## 08-03 条件与真值判断 + +- [ ] 待讨论 + +明确条件接受哪些值、是否转换或允许定制,以及不合法条件如何失败。定制机制依赖【对象与类型模型/定制协议】。 + +## 08-04 短路与条件求值 + +- [ ] 待讨论 + +明确是否支持短路逻辑运算、返回布尔值还是操作数,以及哪些子表达式不会执行。 + +## 08-05 循环形式与正常结束 + +- [ ] 待讨论 + +明确支持哪些循环、条件何时检查、零次执行和正常耗尽的行为;若循环有值,定义正常结束的结果。 + +## 08-06 遍历与迭代协议 + +- [ ] 待讨论 + +明确遍历怎样取得下一项、如何识别结束,以及遍历失败和提前退出时的行为。协议形态依赖【定制协议】。 + +## 08-07 分支及循环的绑定与作用域 + +- [ ] 待讨论 + +明确局部绑定的可见范围、循环变量在各次迭代间的关系、循环后的可见性;检查闭包捕获的交互,依赖【名称与作用域/函数】。 + +## 08-08 `break` + +- [ ] 待讨论 + +明确合法目标、是否携带值、嵌套时如何选择目标,以及目标不存在或值不合法时的行为。 + +## 08-09 `continue` + +- [ ] 待讨论 + +明确合法目标、跳转后执行循环的哪个阶段、是否支持指定外层循环,以及非法位置的行为。 + +## 08-10 `return` + +- [ ] 待讨论 + +明确返回目标、无返回值的行为、函数末尾是否隐式返回,以及在嵌套函数和生成器中的含义。依赖【函数】。 + +## 08-11 模式的种类与匹配含义 + +- [ ] 待讨论 + +明确支持哪些模式、每种模式如何判断成功,以及不支持的形式如何处理。结构读取与相等判断依赖【对象与类型模型/运算符】。 + +## 08-12 匹配顺序与守卫条件 + +- [ ] 待讨论 + +明确分支选择顺序、守卫何时执行、失败后是否继续,以及重叠模式和副作用的行为。 + +## 08-13 匹配覆盖与失败 + +- [ ] 待讨论 + +明确是否要求穷尽、是否允许默认分支、无分支命中的行为,以及不可达分支如何处理。静态检查能力依赖【类型系统】。 + +## 08-14 模式中的变量绑定 + +- [ ] 待讨论 + +明确绑定与已有值比较如何区分、重复变量与组合模式是否合法,以及失败匹配是否留下绑定。 + +## 08-15 生成器的基本控制模型 + +- [ ] 待讨论 + +决定是否支持生成器;若支持,明确创建、启动、暂停、恢复和结束,以及如何交付生成值和最终结果。函数调用形式依赖【函数】。 + +## 08-16 生成器的提前终止与生命周期 + +- [ ] 待讨论 + +若支持生成器,明确主动关闭、内部失败、恢复已结束生成器及重入的行为;明确遗弃生成器时对清理作何保证。依赖【资源管理/内存管理】。 + +## 08-17 异常与执行路径 + +- [ ] 待讨论 + +明确异常怎样穿过条件、循环、匹配和函数,在哪里可以被接住,以及捕获后从哪里继续。异常表示与匹配规则依赖【异常与错误处理】。 + +## 08-18 非正常退出与资源清理 + +- [ ] 待讨论 + +明确 `break`、`continue`、`return`、异常和生成器关闭触发哪些清理、执行顺序,以及清理自身再次退出或失败时谁生效。依赖【异常与错误处理/资源管理】。 + +## 08-19 控制流边界与非法跨越 + +- [ ] 待讨论 + +明确跳转能否跨越函数、闭包、生成器或清理区域,是否支持额外的非局部跳转;给出非法跨越的诊断原则。若其他分类引入异步边界,也在此核对。 + +## 08-20 跨分类一致性验收 + +- [ ] 待讨论 + +用一组涵盖嵌套分支、循环退出、匹配失败、生成器暂停及清理冲突的例子核对最终规则;所有相关依赖均已解决或明确不适用,没有相互矛盾的决定。 + +## 当前问题的方案与语言对照 + +以下沿用原讨论材料;建议和参考语言的做法均不自动成为本语言规则。 + +当前待选的 **08-01** 是:**条件、匹配和循环能否直接产生值?产生的值能否被忽略?** + +相关语言提供了几种不同的安排: + +| 语言 | 规则与小例子 | 取舍及对我们的启发 | +|---|---|---| +| **Python** | `if`、`match`、`for`、`while` 是语句;另有条件表达式:`x = a if ready else b`。[语句规则](https://docs.python.org/3/reference/compound_stmts.html)、[条件表达式](https://docs.python.org/3/reference/expressions.html#conditional-expressions) | 简短选择可以直接产生值;需要多步计算时,通常回到分支赋值或辅助函数。说明“语句为主”仍可以单独提供条件表达式。 | +| **JS/TS** | `if`、`switch` 和循环是语句;条件表达式写成 `const x = ready ? a : b`。TS 在此沿用 JS 的执行语义,并增加静态检查,不是另一套运行时。[ECMAScript 语句](https://tc39.es/ecma262/multipage/ecmascript-language-statements-and-declarations.html)、[条件表达式](https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-conditional-operator)、[TS 类型擦除](https://www.typescriptlang.org/docs/handbook/2/basic-types.html#erased-types) | 与 Python 类似:简单选择紧凑,多步分支不直接作为表达式组合。启发是要区分“单独的条件运算符”与“整个分支块都能产生值”。 | +| **Go** | `if`、`switch`、`for` 是语句,也没有 `?:`;通常先声明变量,再在分支中赋值。[Go 规范](https://go.dev/ref/spec)、[官方 FAQ](https://go.dev/doc/faq#Does_Go_have_a_ternary_form) | 选择结果与执行步骤使用同一种分支结构,规则较少;代价是简单初始化也可能需要多行。适合参考方案 A。 | +| **Rust** | `if`、`match` 是表达式,如 `let x = if ready { a } else { b };`。`loop` 可以用 `break value` 交付结果。[分支规则](https://doc.rust-lang.org/reference/expressions/if-expr.html)、[匹配规则](https://doc.rust-lang.org/reference/expressions/match-expr.html)、[循环规则](https://doc.rust-lang.org/reference/expressions/loop-expr.html) | 多步计算也能直接组合、初始化变量;需要处理各出口的结果兼容性。**但 Rust 的 `while`、`for` 正常结束得到 `()`,不能像 `loop` 那样直接 `break value`。** 表达式化仍然可以区分不同循环。 | + +关于“忽略结果”,Rust 明确支持通过表达式语句求值并丢弃结果;这说明**能够产生值,不必意味着必须接住值**。[Rust 表达式语句](https://doc.rust-lang.org/reference/statements.html#expression-statements) + +回到我们的三个候选方向: + +- **A:控制结构主要是语句。** 简单条件是否另设表达式,需要明确;Python/JS 和 Go 在这里就有区别。 +- **B:`if`、匹配可以产生值,循环是语句。** 分支计算容易组合,循环无需引入结果规则。 +- **C:分支和循环都可以产生值。** 查找、重试可以直接交付结果,但需要定义哪些循环支持、正常耗尽时得到什么。 + +**我的建议是 B,并允许忽略控制表达式的结果。** 它能让多步分支直接初始化变量,又暂时不引入循环结果的额外规则。这只是建议,尚未记为决定;分支缺少 `else` 等细节仍在 `08-02` 处理。 + +你更倾向 **A、B、C** 哪一种?对于能够产生值的控制结构,是否允许直接执行并忽略结果? + +## 讨论来源 + +《语言设计 08:控制流》,整理日期 2026-10-28。章节编号沿用原清单。 + diff --git a/content/docs/language-design/09-questions.md b/content/docs/language-design/09-questions.md new file mode 100644 index 0000000..bbbabeb --- /dev/null +++ b/content/docs/language-design/09-questions.md @@ -0,0 +1,168 @@ +# 09 · 集合与访问协议 + +0/22 项已确认。当前推进 09-01;本分类尚未完成选择。 + +本页整理原讨论的问题、验收要求和候选方案。勾选代表讨论中已确认的规则,不代表编译器或运行时已经实现。 + +## 09-01 能力如何组织 + +- [ ] 待讨论 + +确定下标、迭代、成员判断等能力独立提供、按类别打包,还是允许相互推导;明确组合约束。 + +## 09-02 下标接受什么 + +- [ ] 待讨论 + +确定位置、键、多维下标及其他选择器的支持范围,以及不支持的下标如何失败。 + +## 09-03 读取失败与缺失 + +- [ ] 待讨论 + +确定键不存在、无法读取时的行为,以及如何区分“缺失”和“存储的空值”。依赖「错误处理与结果类型」。 + +## 09-04 下标写入与删除 + +- [ ] 待讨论 + +确定是否分别支持、键不存在时如何处理,以及只读容器上的行为。 + +## 09-05 位置索引规则 + +- [ ] 待讨论 + +确定索引起点、可接受的索引值、负索引、越界与空集合行为。 + +## 09-06 文本索引单位 + +- [ ] 待讨论 + +确定字符串是否支持位置访问,以及访问单位和边界。依赖「字符串与文本」。 + +## 09-07 切片范围规则 + +- [ ] 待讨论 + +确定端点包含关系、默认端点、步长、反向切片、越界与非法步长行为。 + +## 09-08 切片结果语义 + +- [ ] 待讨论 + +确定副本、共享视图或惰性结果的选择规则,以及原集合变化的影响。 + +## 09-09 切片写入与删除 + +- [ ] 待讨论 + +确定支持范围、替换长度要求、重叠操作及失败后的集合状态。 + +## 09-10 长度与有限性 + +- [ ] 待讨论 + +确定哪些对象提供长度,未知或无限长度如何表达,长度是否允许通过遍历计算。 + +## 09-11 获得迭代器与重复遍历 + +- [ ] 待讨论 + +确定如何开始遍历,区分可重复遍历对象与单次消费对象,以及多个遍历是否独立。 + +## 09-12 取下一项与迭代结束 + +- [ ] 待讨论 + +确定元素、正常结束和读取失败的区别,以及结束后再次读取的行为。依赖「错误处理与结果类型」。 + +## 09-13 遍历内容与顺序 + +- [ ] 待讨论 + +确定映射等容器产出什么,各类容器承诺哪些顺序,以及顺序是否稳定。 + +## 09-14 遍历期间修改集合 + +- [ ] 待讨论 + +确定允许的修改、观察到的结果,以及冲突检测和失败行为。 + +## 09-15 提前结束与资源释放 + +- [ ] 待讨论 + +确定退出循环、异常和部分消费时的迭代器处理。依赖「资源管理与控制流」。 + +## 09-16 成员判断的含义 + +- [ ] 待讨论 + +确定判断键、值还是元素,采用何种匹配规则,以及缺失时的结果。依赖「值与相等性」。 + +## 09-17 成员判断的默认实现 + +- [ ] 待讨论 + +确定是否允许退回遍历,以及单次流、无限数据和遍历失败时的行为。 + +## 09-18 解包的数据来源 + +- [ ] 待讨论 + +确定解包依赖迭代、位置访问还是独立协议,以及消费顺序。 + +## 09-19 解包数量与失败 + +- [ ] 待讨论 + +确定数量不足、数量过多、剩余项捕获及无限输入的行为;明确失败时已消费数据和已绑定变量的状态。依赖「绑定与赋值」。 + +## 09-20 自定义容器如何接入 + +- [ ] 待讨论 + +确定用户需要提供哪些操作、哪些有默认行为,以及缺失或冲突如何报告。依赖「类型系统与定制协议」。 + +## 09-21 异步遍历的支持边界 + +- [ ] 待讨论 + +确定本轮是否支持;若支持,明确与同步遍历、取消和清理的关系。依赖「并发与异步」。 + +## 09-22 跨协议一致性验收 + +- [ ] 待讨论 + +检查索引、长度、切片、迭代、成员判断和解包之间的约束;核对相关分类决定,解决冲突。 + +## 当前问题的方案与语言对照 + +以下沿用原讨论材料;建议和参考语言的做法均不自动成为本语言规则。 + +当前仍是 **09-01:下标、迭代、成员判断等能力如何组织**。核心问题是:支持一种能力,是否自动获得其他能力? + +下面的规则来自语言或标准库文档;其中的优缺点是我们的取舍分析,不代表已经确认的历史设计动机。 + +| 语言 | 相关规则与具体行为 | 好处、代价及启发 | +|---|---|---| +| **Python** | 能力分别定制,但有回退:没有 `__contains__` 时,`x in obj` 会尝试迭代,再尝试旧式位置访问。因此 `2 in iter([1, 2, 3])` 为真,同时消费迭代器到 `2`。标准库也提供 `Sequence` 等组合契约。[数据模型](https://docs.python.org/3/reference/datamodel.html#object.__contains__)、[容器抽象](https://docs.python.org/3/library/collections.abc.html) | 定制操作较少也能获得便利;但成员判断可能隐含消费和长时间搜索。说明“独立能力”“组合契约”“默认推导”可以分层存在。 | +| **JS** | 迭代通过 `Symbol.iterator`,与下标访问分开。`{0: "a", length: 1}` 能读取 `[0]`,却不能直接用于 `for...of`。`Map` 通过 `.has(k)` 判断键是否存在;JS 的 `in` 检查对象属性,并非通用集合成员判断。[迭代协议](https://tc39.es/ecma262/2025/multipage/abstract-operations.html#sec-getiterator)、[属性判断](https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-relational-operators-runtime-semantics-evaluation)、[Map.has](https://tc39.es/ecma262/2025/multipage/keyed-collections.html#sec-map.prototype.has) | 能力边界较明确;不同容器的查询接口也可能不同。启发是:统一语法与统一能力是两个决定。 | +| **TS** | 用静态类型分别表达能力,例如 `ArrayLike` 描述数字下标和长度,`Iterable` 描述可迭代;只有前者不保证满足后者。执行仍依赖生成的 JS、运行环境及编译配置,TS 没有独立运行时。[对象类型](https://www.typescriptlang.org/docs/handbook/2/objects.html)、[迭代类型](https://www.typescriptlang.org/docs/handbook/iterators-and-generators.html) | 可以提前检查算法需要的能力;类型声明仍需与运行行为一致。我们可以先决定语义,再决定是否静态检查。 | +| **Go** | 内置下标适用于规定的类型,不能靠给任意结构体添加方法来重载 `[]`;`range` 有独立规则,Go 1.23 起支持规定签名的迭代函数。例如通道可以被 `range` 遍历,却不能下标访问。[语言规范](https://go.dev/ref/spec) | 内置规则集中明确;自定义容器接入下标语法的空间较小。说明访问与遍历也可以采用不同的扩展机制。 | +| **Rust** | `Index` 与 `IntoIterator` 是分开的 trait。自定义类型只实现 `Index`,不会因此获得 `for` 遍历。通用搜索可显式写成 `iter.any(|x| x == 42)`,会推进迭代器直到匹配或结束。[Index](https://doc.rust-lang.org/std/ops/trait.Index.html)、[IntoIterator](https://doc.rust-lang.org/std/iter/trait.IntoIterator.html)、[any](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.any) | 能力要求明确,搜索也能复用;自定义类型需要提供对应能力。说明“提供通用算法”不必意味着“自动赋予另一项协议”。 | + +这些语言都混合使用了多种机制,不能简单把整门语言归为某一个方案。我们当前仍选这三个方向之一: + +- **A.按类别打包**:序列、映射等各自规定必需能力;特殊容器可能需要适配。 +- **B.能力独立**:可下标不自动意味着可迭代,可迭代不自动意味着支持成员判断;通用搜索可以显式调用。 +- **C.能力独立并允许默认推导**:例如没有专门成员判断时,自动遍历;具体回退规则在后续任务明确。 + +**我建议 B**:目前语言用途尚未确定,先独立表达能力,可以容纳数组、映射和单次输入流;常用能力仍可组合成契约。代价是自定义容器可能要多提供几个操作。这只是建议,尚未成为决定。 + +你倾向 **A、B,还是 C**? + +## 讨论来源 + +《语言设计 09:集合与访问协议》,整理日期 2026-10-28。章节编号沿用原清单。 + diff --git a/content/docs/language-design/10-questions.md b/content/docs/language-design/10-questions.md new file mode 100644 index 0000000..2ad32d8 --- /dev/null +++ b/content/docs/language-design/10-questions.md @@ -0,0 +1,136 @@ +# 10 · 错误与资源 + +0/16 项已确认。当前推进 10-01;本分类尚未完成选择。 + +本页整理原讨论的问题、验收要求和候选方案。勾选代表讨论中已确认的规则,不代表编译器或运行时已经实现。 + +## 10-01 失败的基本控制流 + +- [ ] 待讨论 + +确定使用错误结果、异常还是混合机制,以及失败后调用处如何继续。 + +## 10-02 错误的表示与分类 + +- [ ] 待讨论 + +确定错误携带哪些信息、如何区分类别和匹配处理器,是否允许自定义错误。依赖【对象与类型模型】。 + +## 10-03 失败是否属于接口契约 + +- [ ] 待讨论 + +确定函数是否声明可能的失败、调用者是否必须处理,以及遗漏处理如何检查。依赖【类型系统】。 + +## 10-04 向上传播与机制转换 + +- [ ] 待讨论 + +确定自动或显式传播规则,以及错误结果与异常之间是否允许转换、转换保留什么信息。 + +## 10-05 捕获与恢复 + +- [ ] 待讨论 + +确定处理器的匹配顺序、可见范围、重新传播,以及处理后从哪里继续;明确是否支持回到失败点继续执行。 + +## 10-06 退出作用域与栈展开 + +- [ ] 待讨论 + +确定错误跨越调用和作用域时的退出顺序,哪些清理必须执行,以及清理能访问哪些仍有效的数据。 + +## 10-07 清理结构与执行时机 + +- [ ] 待讨论 + +决定支持哪些 `finally`、`defer` 或资源作用域机制,明确注册时机、执行顺序,以及正常结束、提前返回和错误退出的行为。 + +## 10-08 资源责任与关闭规则 + +- [ ] 待讨论 + +确定谁负责关闭、责任能否转移,以及共享、重复关闭和关闭后使用如何处理。依赖【所有权与生命周期/类型系统】。 + +## 10-09 清理过程中再次失败 + +- [ ] 待讨论 + +确定原始错误与清理错误如何保留,后续清理是否继续,以及最终向外报告什么。 + +## 10-10 析构、终结与 GC 的边界 + +- [ ] 待讨论 + +确定是否提供析构或终结机制、执行保证及限制,明确内存回收能否承担资源关闭责任。依赖【内存管理与运行时】。 + +## 10-11 不可恢复失败与终止 + +- [ ] 待讨论 + +区分可处理失败、程序缺陷和强制终止;确定各类情况下是否展开和清理,以及未处理错误到达程序边界后的行为。 + +## 10-12 异步操作与取消中的清理 + +- [ ] 待讨论 + +明确是否支持异步清理、取消如何传播,以及清理期间再次取消的行为。依赖【并发与异步】。 + +## 10-13 并发中的多个失败 + +- [ ] 待讨论 + +确定任务失败由谁接收,多个失败如何组合,其他任务是否继续或取消。依赖【并发与异步】。 + +## 10-14 资源协议与外部接口边界 + +- [ ] 待讨论 + +明确语言内置保证与库协议的分工,以及外部调用的错误如何进入本语言、跨越外部调用时谁负责清理。依赖【定制协议、标准库与外部互操作】。 + +## 10-15 错误诊断与上下文保留 + +- [ ] 待讨论 + +确定是否保留调用位置、传播路径、原始原因与附加上下文,以及包装、重抛后保留什么。 + +## 10-16 跨分类一致性验收 + +- [ ] 待讨论 + +用正常返回、嵌套失败、清理失败、未处理失败及适用的取消场景核对全部规则,消除与其他分类决定的冲突和阻塞。 + +## 当前问题的方案与语言对照 + +以下沿用原讨论材料;建议和参考语言的做法均不自动成为本语言规则。 + +当前仍是 **10-01:常规操作失败时,返回失败结果,还是直接中断控制流?** 这里先讨论文件不存在、配置格式错误等情况,致命故障留到 10-11。 + +**相关语言怎样做** + +| 语言 | 规则与小例子 | 好处、代价与启发 | +|---|---|---| +| **Python** | 广泛使用异常。例如 `int("abc")` 抛出 `ValueError`,跳过当前路径中的后续语句,寻找匹配的 `except`;中间函数不必逐层转发。也允许接口返回普通错误结果。[官方文档](https://docs.python.org/3/tutorial/errors.html) | 正常路径紧凑,便于外层集中处理;调用表达式本身通常看不出可能抛什么。启发:选择异常,就要接受并管理这种隐式退出路径。 | +| **JS** | 支持 `throw` 和 `try/catch`,可抛出任意值。例如 `throw "bad config"` 会中断当前路径,由外层捕获。[语言规范](https://tc39.es/ecma262/multipage/ecmascript-language-statements-and-declarations.html#sec-throw-statement) | 传播方便,但处理器不能天然假定拿到的是标准错误对象。启发:**采用异常**与**允许抛什么**是两个独立决定。 | +| **TS** | 运行时沿用 JS 的异常行为。静态检查可以约束错误的使用:启用 `useUnknownInCatchVariables` 时,捕获值默认为 `unknown`,访问其属性前需要缩小类型;这不等于静态列出函数可能抛出的错误。[官方文档](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-4.html#defaulting-to-the-unknown-type-in-catch-variables---useunknownincatchvariables) | 能提高处理代码的安全性,却不会自动消除隐式异常路径。启发:静态类型检查与失败控制流要分别设计。 | +| **Go** | 常规错误通常作为额外返回值,例如得到 `(文件, error)` 后检查 `err != nil`;返回错误本身不会自动退出调用者。另有 `panic/recover` 机制。[官方说明](https://go.dev/doc/effective_go#errors) | 检查与返回位置明确;逐层传播容易重复,也可能忽略错误。启发:显式错误值和另一种中断机制可以并存,但需要明确用途。 | +| **Rust** | 常规可恢复错误使用 `Result`,区分 `Ok` 与 `Err`。例如 `File::open(path)?` 在失败时提前返回当前函数;不用 `?` 时,可检查或传递这个结果。[官方文档](https://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html) | 结果结构清楚,传播简写减少重复;需要相应的类型与转换规则。启发:**显式结果并不要求每次手写完整分支**,传播语法可以另行设计。 | + +这些实践提供参考,不替我们作决定;表中的好处与代价是取舍分析,不是对历史设计动机的断言。 + +**我们当前的三个候选方案** + +沿用“配置文件不存在就使用默认配置,格式错误就停止启动”的例子: + +- **A.常规失败统一返回显式结果**:调用者检查或显式传播。可以随后讨论传播简写,无须现在确定类型语法。 +- **B.常规失败统一通过异常传播**:调用者捕获“文件不存在”来恢复,格式错误继续向外传播。 +- **C.两者并存**:允许不同接口选择,但必须进一步确定分工,避免调用者不清楚该检查返回值还是捕获异常。 + +我的暂时建议是优先考虑 **A**:它让失败路径容易在调用处辨认,也能通过传播简写减少重复。如果你更重视多层调用后集中处理错误,**B** 更值得选。选择 **C** 则需要有明确的两类使用场景,收益才足以抵消复杂度。语言用途尚未确定,这个建议仍是候选。 + +你更倾向 **A、B,还是 C**? + +## 讨论来源 + +《语言设计 10:错误与资源》,整理日期 2026-10-28。章节编号沿用原清单。 + diff --git a/content/docs/language-design/11-questions.md b/content/docs/language-design/11-questions.md new file mode 100644 index 0000000..93a1c8b --- /dev/null +++ b/content/docs/language-design/11-questions.md @@ -0,0 +1,168 @@ +# 11 · 模块与程序执行 + +0/22 项已确认。当前推进 11-01;本分类尚未完成选择。 + +本页整理原讨论的问题、验收要求和候选方案。勾选代表讨论中已确认的规则,不代表编译器或运行时已经实现。 + +## 11-01 模块的职责与顶层内容 + +- [ ] 待讨论 + +明确模块主要承载声明、可执行初始化,还是可实例化的定义;说明导入与执行的关系。 + +## 11-02 模块的组织单位 + +- [ ] 待讨论 + +明确模块与文件、目录、包的对应关系,以及嵌套模块、多文件模块是否支持;说明不合法的组织形式。 + +## 11-03 模块身份 + +- [ ] 待讨论 + +明确判断“同一个模块”的依据;覆盖路径别名、重复引用及不同版本,说明身份冲突如何处理。 + +## 11-04 名称与路径解析 + +- [ ] 待讨论 + +明确绝对引用、相对引用、搜索位置及优先级;说明找不到目标、存在多个候选时的行为。 + +## 11-05 依赖与版本选择 + +- [ ] 待讨论 + +明确依赖由谁声明、版本由谁选择,能否同时使用多个版本;划清语言、构建工具和包管理器的职责。 + +## 11-06 导出与可见性 + +- [ ] 待讨论 + +明确默认公开范围、显式导出及内部成员的访问规则;说明越权引用如何失败。依赖【名称与作用域】。 + +## 11-07 导入形式与名称冲突 + +- [ ] 待讨论 + +明确整体导入、成员导入、别名、重新导出和批量导入的支持范围;说明重名与遮蔽规则。 + +## 11-08 跨模块绑定语义 + +- [ ] 待讨论 + +明确导入获得值、持续关联的绑定,还是其他形式;说明重新赋值和修改共享对象的区别。依赖【名称与作用域】【对象与类型模型】。 + +## 11-09 依赖检查与条件导入 + +- [ ] 待讨论 + +明确依赖必须何时可用,是否支持可选或条件导入;说明未使用但缺失的依赖是否导致失败。依赖【编译与执行方式】。 + +## 11-10 初始化触发与次数 + +- [ ] 待讨论 + +明确初始化何时发生、何种范围内执行几次,以及重复导入的行为。 + +## 11-11 初始化顺序与并发 + +- [ ] 待讨论 + +明确依赖之间的初始化顺序,是否允许并发或异步初始化;说明顺序不确定时有哪些保证。依赖【并发与异步】。 + +## 11-12 循环依赖 + +- [ ] 待讨论 + +明确允许哪些循环,何时检测;说明访问尚未准备好的定义或状态如何处理。 + +## 11-13 初始化失败 + +- [ ] 待讨论 + +明确失败后模块处于什么状态,能否重试,如何处理已发生的副作用,以及依赖方会得到什么结果。依赖【错误处理】。 + +## 11-14 模块状态与隔离 + +- [ ] 待讨论 + +明确是否允许可变模块状态、由谁持有、何时结束,以及多个程序环境能否相互隔离。依赖【内存与资源管理】。 + +## 11-15 程序入口的确定 + +- [ ] 待讨论 + +明确入口是指定函数、指定模块、顶层代码还是其他形式;说明缺失或存在多个入口时如何处理。 + +## 11-16 入口的输入输出契约 + +- [ ] 待讨论 + +明确参数如何传入、入口允许返回什么,以及如何形成退出结果;说明不合法的入口签名。依赖【类型系统】【标准库与宿主接口】。 + +## 11-17 启动流程 + +- [ ] 待讨论 + +明确依赖准备、模块初始化与入口执行的先后关系;说明启动中途失败时入口和清理是否执行。 + +## 11-18 动态装载与模块生命周期 + +- [ ] 待讨论 + +明确是否支持运行中加载、重新加载和卸载;如支持,说明旧引用、状态与资源的去向;如不支持,记录限制。 + +## 11-19 正常结束 + +- [ ] 待讨论 + +明确入口返回、显式退出与后台工作之间的关系;说明哪些条件代表程序真正结束。依赖【并发与异步】。 + +## 11-20 异常与外部终止 + +- [ ] 待讨论 + +明确未处理错误、取消、外部终止请求和强制终止分别有什么保证;说明错误报告与退出结果。依赖【错误处理】【并发与异步】【宿主接口】。 + +## 11-21 清理协议与顺序 + +- [ ] 待讨论 + +明确清理动作如何注册或归属、执行顺序、能否异步,以及清理自身失败或重复触发的处理。依赖【内存与资源管理】【错误处理】。 + +## 11-22 跨分类一致性验收 + +- [ ] 待讨论 + +用普通启动、共享依赖、循环依赖、初始化失败和退出清理等完整场景检查规则;相关分类决定已对齐,且没有未解决的阻塞,才可完成。 + +## 当前问题的方案与语言对照 + +以下沿用原讨论材料;建议和参考语言的做法均不自动成为本语言规则。 + +当前仍是 **11-01:模块的职责与顶层内容**。要决定的是:模块顶层能否执行读取配置、打开连接等动作,以及这些动作是否由导入自动触发。 + +相关语言的对照如下。下述好处与代价是设计取舍分析,不是在断言它们的历史设计动机。 + +| 语言 | 规则与具体行为 | 取舍及对我们的启发 | +|---|---|---| +| **Python** | 对普通源码模块,常规首次导入会执行模块代码。例如顶层 `current = read_config()` 会在导入时调用函数;后续命中模块缓存时通常不再执行。这里说的是 Python 导入规则,并非 CPython 独有的优化。[官方参考](https://docs.python.org/3/reference/import.html#loading) | 顶层写法直接,容易提供共享状态;但一次导入可能读文件、修改环境或抛出异常。对应我们的 **B**。 | +| **JS:ES Modules** | 模块允许顶层语句。例如模块中写 `console.log("loaded")`,该模块被求值时就会打印;普通静态导入会使依赖参与求值。导入声明的连接过程与模块代码求值是不同阶段。这里专指 ESM,CommonJS 另有规则。[ECMAScript 规范](https://tc39.es/ecma262/multipage/ecmascript-language-scripts-and-modules.html#sec-modules) | 能自动执行依赖的准备动作;也需要处理副作用、初始化顺序和失败。提醒我们区分“找到并连接定义”和“执行初始化”。 | +| **TS** | 运行时模块行为由实际采用的 JS 模块格式和宿主决定,TS 不提供独立运行时。`import type { Config } ...` 会从输出 JS 中消除,因此这条导入本身不会触发运行时加载。[官方文档](https://www.typescriptlang.org/docs/handbook/modules/reference#type-only-imports-and-exports) | 类型依赖可以与运行时依赖分开,但要明确两者的区别。启发是:需要一个类型,不一定需要运行其所属模块;是否采用该机制留给后续任务。 | +| **Go** | 包顶层不能任意写执行语句,但变量初始化可以调用函数,如 `var current = readConfig()`;还可以写自动执行的 `func init()`。程序启动时先初始化依赖包,再运行入口。[语言规范](https://go.dev/ref/spec#Package_initialization) | 顶层结构规整,仍可自动准备共享状态;副作用仍可能藏在变量初始化里。说明**“顶层只准声明”并不等于“没有自动执行”**。 | +| **Rust** | 模块是定义项的容器,没有普通的“导入即执行模块体”机制。直接在模块体中写 `read_config();` 不合法;普通 `static` 的初始化表达式要求能在编译期求值,不能直接读取运行时配置文件。可把读取动作放入函数,由调用者调用。[模块规则](https://doc.rust-lang.org/reference/items/modules.html)、[静态项规则](https://doc.rust-lang.org/reference/items/static-items.html) | 普通模块使用不会自动读取配置,启动动作更明确;调用者需要组织初始化。对应我们的 **A** 方向。 | + +还有一点需要澄清:**A、B 两种模块都可以导出 `create(config)` 这样的普通函数,用它创建多个独立状态。** 只有当我们希望语言本身支持“创建模块实例、给实例连接依赖”时,才需要之前的 **C**;普通对象或函数已经能解决不少隔离需求。 + +因此当前三个选择保持不变: + +- **A.显式调用**:模块提供定义;读取配置等运行时动作放入函数,由调用者启动。还需明确允许哪些顶层初始化表达式,才能保证声明中不会暗藏这些动作。 +- **B.自动初始化**:模块可以带运行时初始化,使用模块时由系统安排执行;触发时机、次数和失败处理分别在后续任务决定。 +- **C.显式模块实例**:导入定义后,由调用者创建带状态的模块实例;语言需要提供实例创建和依赖连接规则。 + +**我暂建议 A**:它让初始化失败发生在明确的调用处,也方便调用者决定状态如何共享。代价是程序需要多写一些启动与状态传递代码。如果你希望模块直接提供“准备好的共享服务”,B 会更顺手。这个建议尚未成为决定。 + +## 讨论来源 + +《语言设计 11:模块与程序执行》,整理日期 2026-10-28。章节编号沿用原清单。 + diff --git a/content/docs/language-design/12-questions.md b/content/docs/language-design/12-questions.md new file mode 100644 index 0000000..9b42514 --- /dev/null +++ b/content/docs/language-design/12-questions.md @@ -0,0 +1,163 @@ +# 12 · 并发与异步 + +0/21 项已确认。当前推进 12-01;本分类尚未完成选择。 + +本页整理原讨论的问题、验收要求和候选方案。勾选代表讨论中已确认的规则,不代表编译器或运行时已经实现。 + +## 12-01 可变状态的共享规则 + +- [ ] 待讨论 + +确定普通可变值默认能否跨执行单位共享,以及允许共享的条件、违规后果。 + +## 12-02 数据跨边界传递 + +- [ ] 待讨论 + +确定参数、闭包捕获和消息采用复制、共享还是转移;明确嵌套引用及发送后继续访问的规则。依赖:对象与类型模型。 + +## 12-03 支持哪些执行单位 + +- [ ] 待讨论 + +确定是否提供线程、任务、协程或其他单位,明确各自能力及相互关系;不支持的单位也明确记录。 + +## 12-04 并行能力与边界 + +- [ ] 待讨论 + +确定哪些执行单位允许同时执行,哪些必须串行,以及程序能否依赖特定并行度。 + +## 12-05 创建、启动与生命周期 + +- [ ] 待讨论 + +确定工作何时启动、由谁管理、能否脱离创建者,以及作用域退出时如何处理未结束工作。 + +## 12-06 等待结果与失败传播 + +- [ ] 待讨论 + +确定等待一次或多次的行为、结果保存方式、未观察错误,以及多个子任务失败时的处理。依赖:异常与错误处理。 + +## 12-07 异步暂停与调用规则 + +- [ ] 待讨论 + +确定暂停是否显式、哪些上下文允许等待、可等待值的协议,以及普通调用与异步调用如何组合。依赖:函数与定制协议。 + +## 12-08 阻塞操作与异步的衔接 + +- [ ] 待讨论 + +确定同步 I/O、阻塞调用进入任务后的行为,以及是否提供转交线程等机制;明确误用后果。 + +## 12-09 取消与清理 + +- [ ] 待讨论 + +确定谁能请求取消、何时生效、能否屏蔽、如何观察取消,以及清理代码能否继续等待。依赖:资源管理、异常与错误处理。 + +## 12-10 超时与竞争等待 + +- [ ] 待讨论 + +确定超时是否取消工作、多路等待如何选胜者、同时完成如何处理,以及落选工作由谁回收。 + +## 12-11 调度与进展保证 + +- [ ] 待讨论 + +确定切换时机、协作式或抢占式约束、饥饿与公平性保证,以及执行单位能否迁移线程。 + +## 12-12 显式同步工具 + +- [ ] 待讨论 + +确定支持哪些锁、条件变量或信号量;明确重入、持锁暂停、取消等待和死锁的处理。 + +## 12-13 消息与通道 + +- [ ] 待讨论 + +确定是否支持消息机制;若支持,明确顺序、容量、背压、关闭、发送失败与接收结束的行为。 + +## 12-14 原子操作 + +- [ ] 待讨论 + +确定是否提供原子值及操作;若支持,明确操作范围、内存顺序和不支持的值类型。依赖:类型系统、数值与基础类型。 + +## 12-15 内存可见性与数据竞争 + +- [ ] 待讨论 + +明确同步建立什么可见性保证,以及未同步冲突访问是被拒绝、报错,还是具有某种规定的后果。 + +## 12-16 运行时自身的并发保护 + +- [ ] 待讨论 + +明确 GIL、对象级锁、隔离堆等候选机制必须保障什么,以及哪些实现选择可以保留自由;区分运行时安全与用户操作的原子性。依赖:运行时实现。 + +## 12-17 复合操作与重入 + +- [ ] 待讨论 + +明确单次安全操作能否组合成事务;规定回调、用户代码重入及跨多个值维护不变量时的保证。依赖:对象与定制协议。 + +## 12-18 资源与对象生命周期的交互 + +- [ ] 待讨论 + +明确任务退出、共享对象存活、资源关闭、终结处理与并发访问发生冲突时的规则。依赖:内存管理、资源管理。 + +## 12-19 外部代码与外来线程 + +- [ ] 待讨论 + +确定是否支持外部阻塞调用、外来线程进入语言和跨边界回调;明确同步责任及违规后果。依赖:外部接口、运行时实现。 + +## 12-20 执行上下文与局部状态 + +- [ ] 待讨论 + +确定线程局部、任务局部或等价机制是否存在,以及创建、迁移、取消时如何继承和释放。 + +## 12-21 跨分类一致性与最终验收 + +- [ ] 待讨论 + +用代表性场景检查上述规则能否共同成立,解决跨分类冲突,并形成最终规则摘要。 + +## 当前问题的方案与语言对照 + +以下沿用原讨论材料;建议和参考语言的做法均不自动成为本语言规则。 + +当前仍是 **12-01:普通可变数据能否跨执行单位直接共享,以及谁负责保证安全。** 这里允许不同边界采用不同规则,例如同一线程内的任务与可能并行的工作之间,可以有不同限制。 + +现有语言提供了四种有用的参考: + +| 语言 | 规则与具体行为 | 好处、代价及启发 | +|---|---|---| +| **Python** | 同一解释器中的线程可以持有同一个列表、字典等对象。程序员可以用同一把锁保护“检查库存+扣减”。GIL 是 CPython 的实现机制;CPython 也有自由线程构建,内置容器的内部保护不能替代业务同步。[官方文档](https://docs.python.org/3.14/howto/free-threading-python.html) | 共享方便,但同步责任主要由程序员承担。启发:必须分别说明“对象内部安全”和“整段业务操作正确”。 | +| **JS/TS** | 同一 JS agent 内的异步工作可以访问同一个普通对象;跨 `await` 的操作仍可能交错。浏览器 Worker 之间通常通过消息复制或转移数据,不能直接共享普通对象;共享内存可显式使用 `SharedArrayBuffer`,配合原子操作。Worker 属于宿主提供的机制。[ECMAScript](https://tc39.es/ecma262/multipage/executable-code-and-execution-contexts.html#sec-agents)、[HTML 标准](https://html.spec.whatwg.org/multipage/workers.html) | 普通对象跨 Worker 的隔离减少直接共享风险,但有传递成本;显式共享内存增加复杂性。启发:可以采用“局部共享、跨并行边界默认隔离”。 | +| **Go** | goroutine 可以直接共享变量,但冲突访问必须同步。例如两个 goroutine 访问同一库存,可以用 `sync.Mutex` 保护;也可以让一个 goroutine 管理库存,其他工作通过 channel 请求。channel 不会自动剥夺发送者对所发送指针的访问权。[内存模型](https://go.dev/ref/mem)、[Effective Go](https://go.dev/doc/effective_go#sharing) | 共享内存和消息协作都方便;“发送后不再访问”通常需要程序员遵守。启发:提供消息工具与强制隔离是两个不同决定。 | +| **Rust** | 安全 Rust 通过所有权、借用和跨线程约束限制危险共享。共享修改库存可以使用 `Arc>`;访问锁内数据需要取得锁守卫,普通 `Rc` 则不能直接跨线程传递。[官方教程](https://doc.rust-lang.org/book/ch16-03-shared-state.html) | 能提前拒绝部分危险访问,但规则和类型更复杂,也仍可能死锁或出现业务竞态。启发:可以把“满足条件才能共享”做成可检查的规则。 | + +其中,**TS 没有独立的并发运行时**,实际行为依赖生成的 JS 和宿主环境。`readonly` 等静态限制也不会自动提供运行时冻结或同步保护。[TS 对象类型文档](https://www.typescriptlang.org/docs/handbook/2/objects.html#readonly-properties) + +回到我们的三个候选方向: + +- **A.默认允许共享,使用者负责同步。** 接近 Python 线程、Go 共享变量的使用方式。表达直接,但容易遗漏同步。 +- **B.跨并行边界默认隔离,通过消息协作。** 可以参考浏览器 Worker 的普通对象边界。管理责任清楚,但必须明确复制、转移和响应规则。 +- **C.只有满足检查规则才能共享或转移。** 可以参考 Rust。能更早发现危险用法,但依赖更完整的别名、所有权或运行期检查设计。 + +**我的暂定建议是优先考虑 B**:先让普通可变数据跨并行边界的归属清楚,再讨论是否提供显式共享机制。它也有成本:频繁交换大型数据时,需要认真设计传递方式。如果我们的目标更偏向细粒度共享和底层控制,C 值得优先考虑。这个建议尚未成为决定。 + +你更倾向 **A 的直接共享、B 的默认隔离,还是 C 的受检查共享**?如果你的偏好是“同一线程内共享、跨并行边界隔离”,也可以直接这样确定方向。 + +## 讨论来源 + +《语言设计 12:并发与异步》,整理日期 2026-10-28。章节编号沿用原清单。 + diff --git a/content/docs/language-design/13-questions.md b/content/docs/language-design/13-questions.md new file mode 100644 index 0000000..4314b7c --- /dev/null +++ b/content/docs/language-design/13-questions.md @@ -0,0 +1,175 @@ +# 13 · 外部交互 + +0/22 项已确认。当前推进 13-01;本分类尚未完成选择。 + +本页整理原讨论的问题、验收要求和候选方案。勾选代表讨论中已确认的规则,不代表编译器或运行时已经实现。 + +## 13-01 外部交互的默认安全边界 + +- [ ] 待讨论 + +明确普通代码默认能否接触外部地址、依靠谁保证安全,以及是否提供不安全入口。 + +## 13-02 I/O 的基础接口单位 + +- [ ] 待讨论 + +明确字节、文本、流、消息之间的基础关系,以及哪些能力由上层封装提供。 + +## 13-03 I/O 的执行方式 + +- [ ] 待讨论 + +明确阻塞、异步是否支持,默认方式,以及超时和取消对操作结果的影响。依赖【并发与执行模型】。 + +## 13-04 文件与路径接口 + +- [ ] 待讨论 + +明确路径如何表示,文件如何打开,以及创建、覆盖、追加和访问失败的规则。 + +## 13-05 网络接口范围 + +- [ ] 待讨论 + +明确本轮支持哪些通信抽象,以及连接、监听、半关闭和断开的基本行为;明确不支持的能力。 + +## 13-06 I/O 的部分成功与结束状态 + +- [ ] 待讨论 + +明确短读、短写、EOF、暂不可用、部分完成后失败如何区分和报告。 + +## 13-07 外部资源的关闭规则 + +- [ ] 待讨论 + +明确谁负责关闭、重复关闭和关闭后使用的行为,以及自动清理是否保证及时发生。依赖【资源管理】。 + +## 13-08 FFI 支持范围与调用约定 + +- [ ] 待讨论 + +明确支持哪些外部调用目标、是否支持向外导出函数,以及变参等特殊接口的支持边界。依赖【目标平台与执行方式】。 + +## 13-09 外部声明与符号解析 + +- [ ] 待讨论 + +明确外部函数如何声明、库和符号何时解析,以及缺失、重复或声明不匹配时的行为。依赖【模块系统】。 + +## 13-10 基础类型映射 + +- [ ] 待讨论 + +明确整数宽度与符号、浮点、布尔、空值、指针的对应关系,以及不能表示时的处理。 + +## 13-11 复合类型与数据布局 + +- [ ] 待讨论 + +明确结构体、数组、枚举等如何传递,哪些布局可以公开,以及大小、对齐、填充如何确定。依赖【类型与数据模型】。 + +## 13-12 字符串与编码 + +- [ ] 待讨论 + +明确编码、长度单位、终止符、内嵌零值和非法编码的处理,以及转换责任。 + +## 13-13 缓冲区访问契约 + +- [ ] 待讨论 + +明确只读或可写、连续性、复制或共享、借用期限,以及外部保存地址时的要求。依赖【内存管理】。 + +## 13-14 内存所有权与分配器配对 + +- [ ] 待讨论 + +明确跨边界分配、转移、释放的责任,以及由哪个分配器或释放函数回收。 + +## 13-15 不透明句柄与运行时值映射 + +- [ ] 待讨论 + +明确外部资源或复杂值如何表示,是否允许直接暴露语言内部值,以及无效句柄的处理。依赖【对象与类型模型】。 + +## 13-16 回调的注册与生命周期 + +- [ ] 待讨论 + +明确回调如何传递、保存、注销,如何保活其上下文,以及注销后迟到调用的处理。 + +## 13-17 外部线程与重入 + +- [ ] 待讨论 + +明确哪些线程能进入运行时、是否允许嵌套调用,以及违反约束时的行为。依赖【并发与运行时】。 + +## 13-18 跨边界错误传递 + +- [ ] 待讨论 + +明确错误码、异常和取消怎样转换,是否允许栈展开越过边界,以及失败时如何清理。依赖【错误机制】。 + +## 13-19 库卸载与运行时退出 + +- [ ] 待讨论 + +明确仍有句柄、回调或进行中的操作时,能否卸载库或退出运行时,以及处理顺序。 + +## 13-20 跨进程与跨运行时的数据交换 + +- [ ] 待讨论 + +明确是否提供通用交换格式或协议;若提供,规定支持的值、身份或引用关系及转换失败行为。 + +## 13-21 平台差异与接口版本兼容 + +- [ ] 待讨论 + +明确哪些保证跨平台成立,不兼容布局或库版本如何识别,以及无法验证时由谁承担责任。 + +## 13-22 跨分类一致性验收 + +- [ ] 待讨论 + +用文件读取、外部缓冲区、外部返回资源、异步回调四类完整场景,检查上述规则与相关分类是否一致,消除阻塞和冲突。 + +## 当前问题的方案与语言对照 + +以下沿用原讨论材料;建议和参考语言的做法均不自动成为本语言规则。 + +当前仍是 **13-01:外部交互的默认安全边界**。要决定的是:普通代码调用外部库时,内存有效性由谁保证,哪些责任交给底层绑定作者。 + +仍用同一个例子:把字节缓冲区交给外部库,外部库可能立即读取,也可能保存地址、稍后读取。 + +**Python:底层接口可以绕过通常的安全保护。** +以 CPython 提供的 `ctypes` 为例,可以创建缓冲区、传递指针、声明外部函数参数类型。但声明参数类型不等于证明外部访问安全;错误的地址或使用方式可能导致内存损坏、进程崩溃。这种方式方便直接接入本地库,代价是调用者或封装作者承担较多责任。对我们的启发是:**“能声明函数签名”与“能保证生命周期正确”需要分开设计。** [官方文档](https://docs.python.org/3/library/ctypes.html) + +**JS:这里以 Node.js 的原生扩展机制为例,属于宿主提供的能力。** +Node-API 可以把外部内存包装成 JS 可访问的 `Buffer`,并关联回收时调用的清理回调。例如,扩展分配一块内存,再将它暴露给 JS;扩展仍需正确安排其有效期和释放。好处是普通 JS 使用者可以通过熟悉的值访问数据;代价是底层扩展仍然承担内存责任,不同宿主的支持也可能不同。启发是:**上层接口可以简单,但底层责任必须明确。** [Node-API 文档](https://nodejs.org/api/n-api.html#napi_create_external_buffer) + +**TS:增加静态检查,不另提供一套运行时内存保证。** +例如,把接口声明成接受 `Uint8Array`,可以帮助检查调用处的类型,却不能证明原生扩展没有保存过期地址。类型注解会被擦除,运行时行为仍取决于 JS 宿主和扩展。好处是提前发现一部分接口误用;局限是**类型声明本身不能验证外部实现是否守约**。这也提醒我们,方案 B 不能只停留在“多写几个类型”。[TS 官方说明](https://www.typescriptlang.org/docs/handbook/2/basic-types.html#erased-types) + +**Go:cgo 明确限制跨边界指针,并提供复制转换。** +例如,`C.CBytes(data)` 会复制字节到 C 堆,由调用者安排释放;直接向 C 传递 Go 内存则受指针和固定内存规则约束,不能默认让 C 无限期保存。好处是既支持复制也支持受约束共享;代价是绑定作者需要理解两边的内存规则。启发是:**复制与共享可以并存,但应该让使用者知道自己选择了哪种契约。** [cgo 官方文档](https://pkg.go.dev/cmd/cgo) + +**Rust:用显式不安全边界承接无法自动检查的责任,再封装安全接口。** +例如,一个接受“地址+长度”的不安全外部函数,可以被包装成接受字节切片的安全函数;包装作者必须确保长度正确、调用期间内存有效,并确认外部不会在约定期限外使用地址。好处是普通调用者不必反复证明这些条件;代价是包装必须正确,否则安全接口也可能失去保证。启发是:**区分“使用接口的人”与“为接口安全性负责的人”。** [Rust 官方说明](https://doc.rust-lang.org/stable/book/ch20-01-unsafe-rust.html) + +据此,我们的三个选项仍然是: + +| 方案 | 普通使用者默认面对的接口 | 主要代价 | +|---|---|---| +| **A:直接控制地址** | 自己保证地址、长度和生命周期 | 调用方便直接,但内存责任分散到调用处 | +| **B:通过契约绑定** | 使用声明好借用、保留或所有权转移规则的接口 | 绑定设计更复杂,需要信任绑定和外部库守约 | +| **C:主要使用副本与句柄** | 交换独立数据,通过受管理操作访问资源 | 复制与转换开销,部分底层接口较难表达 | + +**我仍建议 B,并保留显式不安全入口供底层绑定使用。** 这样可以把责任集中在绑定层,缓冲区采用复制还是共享则留给 13-13 决定。其保证以绑定和外部库遵守契约为前提;同进程原生代码违约时,不能承诺一定转成可捕获错误,也可能损坏或终止进程。 + +## 讨论来源 + +《语言设计 13:外部交互》,整理日期 2026-10-28。章节编号沿用原清单。 + diff --git a/content/docs/language-design/14-questions.md b/content/docs/language-design/14-questions.md new file mode 100644 index 0000000..24d622f --- /dev/null +++ b/content/docs/language-design/14-questions.md @@ -0,0 +1,136 @@ +# 14 · 反射与表示 + +0/16 项已确认。当前推进 14-01;本分类尚未完成选择。 + +本页整理原讨论的问题、验收要求和候选方案。勾选代表讨论中已确认的规则,不代表编译器或运行时已经实现。 + +## 14-01 运行时反射的基本承诺 + +- [ ] 待讨论 + +确定普通程序默认可以观察哪些信息,哪些需要显式声明,以及元数据是否可以被裁剪。 + +## 14-02 类型查询与类型描述的身份 + +- [ ] 待讨论 + +确定能查询什么、返回什么,如何比较查询结果;明确静态类型、运行时实际类型与抽象接口之间的关系。依赖【类型系统】【对象与类型模型】。 + +## 14-03 元数据的内容与可用性 + +- [ ] 待讨论 + +确定字段名、参数、注解、文档、源码位置等分别是否可查询,以及信息缺失、不同构建配置下的行为。 + +## 14-04 动态读取成员 + +- [ ] 待讨论 + +确定按名称查找的对象范围、查找规则,以及成员不存在、不可访问、读取触发计算时的行为。依赖【对象与类型模型】【定制协议】。 + +## 14-05 动态修改成员 + +- [ ] 待讨论 + +确定是否允许新增、写入、删除成员,以及只读值、类型不匹配和修改失败的行为。依赖【类型系统】【对象与类型模型】。 + +## 14-06 动态调用 + +- [ ] 待讨论 + +确定是否支持通过反射调用函数或成员,以及参数匹配、默认参数和调用失败的规则。依赖【函数与调用】。 + +## 14-07 反射权限与封装 + +- [ ] 待讨论 + +确定查看描述、读取、修改、调用分别需要什么权限,以及跨模块和私有成员的边界。依赖【模块与封装】【安全模型,如有】。 + +## 14-08 调试表示 + +- [ ] 待讨论 + +确定默认调试文本、定制方式、信息隐藏要求,以及是否要求稳定、唯一或可重新解析。 + +## 14-09 用户字符串与格式化 + +- [ ] 待讨论 + +确定用户文本与调试表示的关系、默认回退、格式参数和转换失败行为。依赖【定制协议】【格式化语法】。 + +## 14-10 表示过程的执行边界 + +- [ ] 待讨论 + +确定生成文本能否执行用户代码、产生副作用或抛错,以及循环、递归深度、长度和并发修改的处理。 + +## 14-11 可序列化的值与定制入口 + +- [ ] 待讨论 + +确定哪些值可以保存,如何处理函数、类型描述、外部资源及不支持的值;明确是否依赖反射。依赖【值与资源模型】【定制协议】。 + +## 14-12 数据格式、模式与版本兼容 + +- [ ] 待讨论 + +确定语言承诺与格式库的分工,以及名称、缺失字段、未知字段和版本变化的处理。 + +## 14-13 反序列化与有效状态恢复 + +- [ ] 待讨论 + +确定如何选择目标类型、是否调用构造或校验逻辑,以及无效数据、部分恢复失败的行为。依赖【类型系统】【构造与不变量】【资源管理】。 + +## 14-14 身份、共享引用与循环的保存 + +- [ ] 待讨论 + +确定保存树还是对象图、何时保留共享关系,以及循环、不支持的引用和恢复后身份的语义。依赖【身份与相等性】【内存与引用模型】。 + +## 14-15 反序列化的权限与资源限制 + +- [ ] 待讨论 + +确定输入能否指定类型或执行定制代码,以及不可信数据、超限输入和错误报告的默认规则。依赖【错误处理】【安全模型,如有】。 + +## 14-16 跨分类一致性验收 + +- [ ] 待讨论 + +用一组完整例子核对反射、权限、表示、恢复与相关分类的规则;记录并解决冲突及阻塞。 + +## 当前问题的方案与语言对照 + +以下沿用原讨论材料;建议和参考语言的做法均不自动成为本语言规则。 + +当前仍在讨论 **14-01:普通程序拿到一个陌生值,默认能查询多少结构信息?** 例如,检查工具能否直接知道 `Account` 有 `name` 和 `token` 两个字段? + +下面是相关语言的对照。取舍和启发是我们的分析,不代表这些语言的历史设计动机。 + +| 语言 | 规则与具体行为 | 好处、代价及对我们的启发 | +|---|---|---| +| **Python** | 许多普通实例可用 `vars(x)` 取得属性字典;没有 `__dict__` 的值会报 `TypeError`。`dir(x)` 可以被定制,也不保证列出完整、准确的属性集合。[官方文档](https://docs.python.org/3/library/functions.html#vars) · [dir](https://docs.python.org/3/library/functions.html#dir) | 通用检查很方便,但“列出名称”“实例存储”“所有可访问属性”并不相同。启发:不能只设计一个含糊的“查看所有字段”操作。 | +| **JS** | `Reflect.ownKeys({name: "林"})` 返回 `["name"]`,枚举自身属性键,包括不可枚举属性和 Symbol。`#token` 私有元素不属于普通属性,不会这样列出。[ECMAScript 规范](https://tc39.es/ecma262/multipage/reflection.html#sec-reflect.ownkeys) · [私有元素](https://tc39.es/ecma262/2024/#sec-privateelement-specification-type) | 对普通属性默认可检查,适合动态工具;代价是这些名称成为可观察行为。启发:可以对普通数据开放反射,同时为私有状态设置独立边界。 | +| **TS** | 类型注解、接口等静态信息通常被擦除。例如 `interface Account { name: string }` 不会自动产生可供运行时查询的接口描述;运行时仍使用 JS 的机制。[官方文档](https://www.typescriptlang.org/docs/handbook/2/basic-types.html#erased-types) | 静态检查不必带来完整运行时元数据成本;代价是运行时校验、按接口生成表单等功能需要额外描述。启发:查询对象现有属性与查询静态类型定义必须分开。 | +| **Go** | 标准库 `reflect` 能查询结构体字段,包括未导出字段的描述。但取得描述不等于取得全部操作权限:对来自未导出字段的值调用 `Interface()` 会 panic,修改还受 `CanSet()` 等条件限制。[官方文档](https://pkg.go.dev/reflect) | 通用工具能使用结构元数据,但必须处理权限和操作前提。启发:**知道字段存在、读取字段值、修改字段是不同能力**。 | +| **Rust** | 稳定版标准库的 `Any` 支持类型识别及向具体类型转换,例如 `x.is::()`;它不提供通用字段枚举。`#[derive(Debug)]` 可以生成调试输出代码,这本身不等于开放字段反射。实验性的编译期反射另当别论。[Any 文档](https://doc.rust-lang.org/std/any/index.html) · [derive 文档](https://doc.rust-lang.org/book/appendix-03-derivable-traits.html) | 可以按需提供能力,避免要求所有值都携带通用字段描述;代价是通用工具需要显式适配或生成代码。启发:**调试打印可以独立于运行时结构反射存在**。 | + +这些实践不能直接一一对应我们的选项。一门语言可以同时采用不同规则,例如:普通属性默认可枚举,静态接口被擦除,调试表示又通过显式生成提供。 + +回到 **14-01**,我们的三个方向仍是: + +- **A.不保证通用结构反射**:陌生值只能通过主动提供的接口接受检查。语言承诺较少,通用工具需要更多适配。 +- **B.显式参与结构反射**:只有声明参与或提供描述的值,才能通过统一机制检查。暴露范围可控,但需要维护描述。 +- **C.默认提供结构反射**:对适用的结构化值,默认保证可以查询结构;访问权限另外规定。通用工具方便,但元数据需要成为语言承诺的一部分。 + +我仍建议先考虑 **B**:它让我们能够分别决定反射、调试和序列化的能力。不过语言用途尚未确定,这只是建议,尚未采用。 + +如果选 B,我建议同时确定两个验收边界:**“没有反射描述”必须区别于“有描述但没有字段”;已经承诺可查询的描述,发布构建不能静默裁剪。** 权限规则留给 14-07。 + +你倾向 **A、B、C** 中哪一个?如果选 B,是否一并接受上面两个边界? + +## 讨论来源 + +《语言设计 14:反射与表示》,整理日期 2026-10-28。章节编号沿用原清单。 + diff --git a/content/language-design-sources.json b/content/language-design-sources.json new file mode 100644 index 0000000..7d90e95 --- /dev/null +++ b/content/language-design-sources.json @@ -0,0 +1,129 @@ +{ + "updated": "2026-10-28", + "scope": "Language design questions; discussion status, not implementation status", + "chapters": [ + { + "chapter": "02", + "title": "名称与作用域", + "threadId": "01a1436f-1f6a-7f21-b1cd-32ab787aac46", + "hostId": "local", + "file": "content/docs/language-design/02-questions.md", + "total": 22, + "confirmed": 13 + }, + { + "chapter": "03", + "title": "值与类型", + "threadId": "01a1436f-349f-71f3-a64c-115c282c9dad", + "hostId": "local", + "file": "content/docs/language-design/03-questions.md", + "total": 30, + "confirmed": 13 + }, + { + "chapter": "04", + "title": "存储与生命周期", + "threadId": "01a1436f-4fd8-7392-9789-d8937fec38e1", + "hostId": "local", + "file": "content/docs/language-design/04-questions.md", + "total": 20, + "confirmed": 0 + }, + { + "chapter": "05", + "title": "对象与成员", + "threadId": "01a1436f-61a1-7722-9914-6103691907ce", + "hostId": "local", + "file": "content/docs/language-design/05-questions.md", + "total": 18, + "confirmed": 0 + }, + { + "chapter": "06", + "title": "表达式与运算", + "threadId": "01a1436f-7d66-7cb0-bc59-fac88abd3362", + "hostId": "local", + "file": "content/docs/language-design/06-questions.md", + "total": 20, + "confirmed": 0 + }, + { + "chapter": "07", + "title": "函数与调用", + "threadId": "01a1436f-97bc-74d3-a501-650e893c73c3", + "hostId": "local", + "file": "content/docs/language-design/07-questions.md", + "total": 22, + "confirmed": 0 + }, + { + "chapter": "08", + "title": "控制流", + "threadId": "01a1436f-b115-76d3-800c-e7d090978ceb", + "hostId": "local", + "file": "content/docs/language-design/08-questions.md", + "total": 20, + "confirmed": 0 + }, + { + "chapter": "09", + "title": "集合与访问协议", + "threadId": "01a14370-5360-7550-a595-c693333a2c66", + "hostId": "local", + "file": "content/docs/language-design/09-questions.md", + "total": 22, + "confirmed": 0 + }, + { + "chapter": "10", + "title": "错误与资源", + "threadId": "01a14370-69b3-7090-b66f-4755f71a481a", + "hostId": "local", + "file": "content/docs/language-design/10-questions.md", + "total": 16, + "confirmed": 0 + }, + { + "chapter": "11", + "title": "模块与程序执行", + "threadId": "01a14370-84e7-7de3-b1eb-7707d4e62f83", + "hostId": "local", + "file": "content/docs/language-design/11-questions.md", + "total": 22, + "confirmed": 0 + }, + { + "chapter": "12", + "title": "并发与异步", + "threadId": "01a14370-a1d0-7ca3-951f-315ad8f13b8e", + "hostId": "local", + "file": "content/docs/language-design/12-questions.md", + "total": 21, + "confirmed": 0 + }, + { + "chapter": "13", + "title": "外部交互", + "threadId": "01a14370-b63f-7133-a092-78699b24473e", + "hostId": "local", + "file": "content/docs/language-design/13-questions.md", + "total": 22, + "confirmed": 0 + }, + { + "chapter": "14", + "title": "反射与表示", + "threadId": "01a14370-cc98-7523-8220-a1008ea9b16b", + "hostId": "local", + "file": "content/docs/language-design/14-questions.md", + "total": 16, + "confirmed": 0 + } + ], + "excluded": [ + { + "threadId": "01a11fdf-963c-7d11-87af-65791938d536", + "reason": "Chromium navigation discussion; outside language design" + } + ] +}