Carbon Language 术语去歧义提案解读:精确规范 “generic“、“constant“ 与 “compile-time“ 的语义边界

发布时间:2026/9/11 21:21:51
Carbon Language 术语去歧义提案解读:精确规范 “generic“、“constant“ 与 “compile-time“ 的语义边界 Carbon Language 术语去歧义提案解读精确规范 generic、constant 与 compile-time 的语义边界【免费下载链接】carbon-langCarbon Languages main repository: documents, design, implementation, and related tools. (NOTE: Carbon Language is experimental; see README)项目地址: https://gitcode.com/GitHub_Trending/ca/carbon-lang本文基于 Carbon Language 仓库中的设计提案 Reduce ambiguity in terminologyPR #3162整理而成。该提案针对 Carbon 泛型与常量体系中一个词、多个含义的术语冲突明确了generic type、constant、compile-time等核心术语的精确语义与使用边界。读完本文你将理解 Carbon 为何重定义这些术语、新旧术语的对应关系、表达阶段expression phase体系如何与之衔接以及这些变更在仓库设计文档与工具链源码中的落地情况。问题的起点一个词承载了两种含义提案首先指出现状中 generic type泛型类型一词存在双重含义。以 Carbon 中最典型的泛型声明为例class Vector(T:! type);在这段代码中Vector和T都可以被称作 generic typeVector是一个带有编译期参数的类型parameterized type与 Java、.NET、Swift、Rust 等主流语言社区对 generic type 的通行理解一致T则是由:!绑定引入的类型参数本身按 Types are values of typetype提案中的术语定义generic type 也指由:!绑定引入的类型或 facet。同一个术语指向两个不同的语言实体在规范文档、设计讨论和编译器诊断中都会产生持续的混淆——这正是本提案要解决的第一个问题。类似地constant常量一词在 Carbon 语境中至少承载三种含义编译期求值如 constant evaluation常量求值描述表达式在编译期完成求值的能力不可变绑定如let声明区别于var变量描述一个名称绑定到固定值、不可再赋值只读视图如const T*指针指向的底层类型带const修饰描述一种非修改性的访问视角。这三种含义在实践中的确造成了困惑。提案特别指出constant binding常量绑定一词并不涵盖所有的let绑定——尽管let绑定的值全部不可变但其中的一部分例如绑定到运行时值的let并不属于旧术语所定义的 constant 范畴。术语分歧的历史来源要理解这次术语调整需要回溯 generic type 与 constant 两词各自语义扩张的来龙去脉。generic type 的两种定义路径内部定义提案 p002360-types-are-values-of-type-type.md 中的 terminology 一节将 generic type 定义为由:!绑定引入的类型或 facet典型场景是泛型参数与关联常量associated constant。在这一定义下Vector(T:! type)中的T就是 generic type。社区通行定义在更广泛的编程语言语境中generic 意味着带有编译期参数的语言构造。例如 generic function泛型函数指带编译期参数的函数parameterized types参数化类型被称为 generic types。Rust、Java、.NET、Swift 均采用这一用法。在这一定义下Vector才是 generic type。两种定义长期并存任何阅读 Carbon 设计文档的人都可能在同一段文字中对 generic type 产生不同理解。constant 的语义扩张constant 一词的歧义则来自 Carbon 自身特性的演进早期的 issue #1391 New name for constant value phase 及其实现提案 p002964-expression-phase-terminology.mdPR #2964将 constant 从仅指 template 常量扩展为同时覆盖 checked generics 引入的 symbolic 常量随后提案 p002006-values-variables-pointers-and-references.mdPR #2006在类型系统中引入了const修饰符提供只读视图read-only view能力。于是 constant 一词既要描述编译期求值的阶段属性又要描述let的不可变绑定属性还要描述const T*的只读视图属性。三线并行术语体系出现裂缝。提案核心变更六项术语决议提案给出的解决方案不是发明全新的词汇而是收窄过载词、细化通用词具体包含六项变更1. 保留 generic type 给参数化类型generic type 今后专指带有编译期参数的类型即Vector(T:! type)中的Vector。T不再被称为 generic type从而消除一词二义。这一收窄与 Rust、Java、.NET、Swift 的社区通行用法对齐。2. 扩展 constant binding 覆盖所有let绑定constant binding 的定义被扩展为包含全部let绑定。由于let绑定的值天然不可变constant binding 与 not variable 这一语义对齐任何let引入的名称都可以被称为 constant binding。3. 引入 compile-time binding 作为统称compile-time binding编译期绑定用于指代template binding 与 symbolic binding 的集合典型来源包括泛型参数与关联常量。也就是说凡是绑定值在编译期而非运行时确定、但值本身可能未知或已知的绑定都属于 compile-time binding。4. 用 compile-time constants 替代裸词 constants原 constants 一词被细化为 compile-time constants专指template constants 与 symbolic constants即编译期已知或将在代码生成阶段确定的常量。裸词 constant 不再承担这一职责避免与let、const等其他语义纠缠。5. compile-time parameter 与 generic parameter 并行提案允许以 compile-time parameter编译期参数替代 generic parameter泛型参数。短期内两个词并存使用但从长期看可能更清晰的做法是让 generic 只保留具有编译期参数这一含义。这一条为后续术语收敛预留了空间。6. 只用 symbolic binding 与 template binding不再使用 symbolic constant binding 和 template constant binding 这类叠加词统一简化为 symbolic binding符号绑定与 template binding模板绑定。这一简化与表达阶段术语体系见下文保持一致。附则从 parameter 转向 binding提案还指出凡是适用于编译期参数compile-time parameters的规则几乎都同样适用于编译期绑定compile-time bindings。因此文档在合适的位置应从谈论 parameters 转向谈论 bindings。典型示例见 Generics terminology 文档中的 Bindings 一节 与 facet binding。与表达阶段Expression Phases体系的衔接要真正理解第 3、4、6 条变更需要先看清 Carbon 的表达阶段体系——这是新术语的底层坐标。在 Language design overview 中值表达式value expressions被划分为三个 phaseTemplate constant模板常量值在编译期已知且在类型检查期间即可用例如用作数组大小。包括字面量整型、浮点、字符串、具体类型值如f64、Optional(i32*)、由常量组成的表达式以及template参数的值。Symbolic constant符号常量值在代码生成阶段的单态化monomorphization时才确定类型检查期间未知。包括 checked-generic 参数以及带符号常量实参的类型表达式如Optional(T*)。Runtime value运行时值值仅在运行时动态确定。其中template constants 与 symbolic constants 合称 compile-time constants编译期常量对应着编译期参数的声明。三个 phase 之间存在自动转换template constant → symbolic constant → runtime value运行时值也可以在常量求值成功时反向转换为 template 或 symbolic 常量该反向转换目前是 provisional 状态。对照提案的术语决议可以清晰地看到对应关系旧术语新术语语义generic type指T——不再使用由绑定引入的类型参数generic type指Vectorgeneric type带编译期参数的类型constant binding部分letconstant binding全部let所有不可变绑定constants / constant bindingscompile-time bindingtemplate 与 symbolic 绑定的统称constant编译期求值compile-time constanttemplate 与 symbolic 常量的统称symbolic constant bindingsymbolic bindingchecked generic 绑定template constant bindingtemplate bindingtemplate关键字引入的绑定这一体系在仓库的 Generics terminology 文档 中得到了完整展开绑定模式binding patterns对应三种表达阶段——runtime binding pattern 绑定运行时值显式函数参数的默认checked generic binding pattern 绑定 symbolic constantdeduced 参数与编译期实体的参数默认也是关联常量唯一允许的形式template generic binding pattern 绑定 template constant由template关键字标示表达式是 dependent 的会在实例化提供值后进行延迟类型检查。术语规范在工具链源码中的落地术语变更并非停留在纸面Carbon 工具链的语义 IRSemIR与检查器check实现直接采用了这一套词汇。SemIR 中的 SymbolicConstant 数据结构在 toolchain/sem_ir/constant.h 中SymbolicConstant被定义为Information about a symbolic constant value. These are indexed by aSymbolicConstantId... 一个 symbolic constant 由两个SymbolicConstant表示一个用于 attached 形式、一个用于 unattached 形式。ConstantId体系中专门为 symbolic constant 保留了独立的 ID 空间与索引映射symbolic_constants_用于在类型检查期间对值未知但存在的编译期实体进行统一管理。这正对应术语体系中 symbolic constant 的定位类型检查期间值未知、但可被命名和引用的编译期值。检查器中的 compile_time_binding_stack在 toolchain/check/scope_stack.cpp 中检查器维护了一个compile_time_binding_stack_用于在作用域栈上管理编译期绑定的值CARBON_CHECK(compile_time_binding_stack_.empty(), {0}, compile_time_binding_stack_.all_values_size()); ... static_castint32_t(compile_time_binding_stack_.all_values_size()) ... Wrong number of entries in compile-time binding stack after {0}: have ...这个名字直接印证了 compile-time binding 已成为编译器实现中的一等概念PushArray/PopArray随作用域进出维护绑定栈toolchain/check/generic.cpp 通过compile_time_binding_stack().PeekAllValues()读取当前所有编译期绑定的值。格式化器中的 SymbolicBinding在 toolchain/sem_ir/formatter.cpp 中语义指令SymbolicBinding的注释明确写道A SymbolicBinding with no value is a purely symbolic binding, such as ...可见symbolic binding 在 SemIR 中是一个具体的指令类型inst kindpurely symbolic binding无值的纯符号绑定等用法与提案中只用 symbolic binding / template binding、不再叠加 constant的决议完全一致。从源码结构看Carbon 工具链在 2023 年之后的演进中已经系统性采用 symbolic constant、compile-time binding、SymbolicBinding 等新术语命名数据结构与指令术语决议不是一次性的文档改写而是贯穿了设计与实现的整体收敛。设计文档的同步更新提案同时更新了三份设计文档使术语变更正式进入官方规范Language design overview特别是 Expression phases 一节明确将 template constants 与 symbolic constants 统称为 compile-time constants并引用了本提案PR #3162作为参考来源Generics terminology在 Generic means compile-time parameterized 一节中定义 generic function / generic type / generic interface 均为带至少一个编译期参数的构造在 Bindings 一节中完整给出三种绑定模式与三个表达阶段的对应关系并引入了 facet binding 等细化概念Member access expressions在 Compile-time bindings 小节中讨论了对涉及 compile-time binding 的类型进行成员查找时值未知导致的 symbolic constant 结果与二次查找redo lookup等行为。此外部分术语变更在此提案之前已经由 PR #3048: Update Generics terminology document 和 PR #3061: Update generics overview 先行落地本提案是对这一系列术语收敛工作的正式确认与补全。设计动机为什么值得为用词专门立一项提案术语规范看似只是文字工作但在 Carbon 的语境下它与语言设计目标直接挂钩。提案在 Rationale 一节中援引了 Carbon 项目目标 中的两条语言工具与生态系统Language tools and ecosystem清晰无歧义的术语是编写精确语言规范specification的基础也是所有设计文档与开发者文档质量的前提。规范本身含混工具链、编译器和生态就无法形成一致的行为描述。易于阅读、理解和编写的代码Code that is easy to read, understand, and write其子目标明确要求代码的行为与语义应在可能的情况下被清晰、简单地规定。术语是语义描述的最小单元一个generic type指向两个实体、一个constant承载三种含义直接违背了这一原则。换言之这是一次面向语言规范精度的投资先在词汇层面消除歧义后续的泛型设计、诊断信息与文档表述才能建立在稳固的地基上。备选方案的权衡提案在 Alternatives considered 一节中记录了讨论过程中的主要取舍核心对比对象是维持现状status quo。相关讨论发生于 2023 年 7 月至 8 月的 #naming 频道与开放讨论中主要备选方案包括symbolic type 替代 generic type曾考虑用 symbolic type 指代T但最终被否决——因为 symbolic 已被表达阶段体系占用symbolic constant 指值在类型检查期未知的编译期常量会与既有术语冲突。其他候选名还考虑了 figurative type、computed type、hole type、open type、placeholder type 等其中 placeholder type 被认为或许更适合描述auto而非类型参数本身。关于 generic binding讨论中明确不希望用 generic binding 表示 compile-time binding因为该词更适合指参数化的绑定parameterized binding。这类构造当前 Carbon 尚不支持但属于计划内的能力——例如 Rust 自 v1.65 起支持的泛型关联类型generic associated types。提前把术语让位给未来的特性可以避免日后的二次改词。这些权衡体现了 Carbon 提案流程的一个特点术语决策不仅要解决当下的歧义还要为尚未实现的特性预留命名空间属于典型的设计时决策。结语Reduce ambiguity in terminology 这份提案解决的是一个看似琐碎、实则影响深远的语言工程问题当generic type同时指参数化类型与类型参数、当constant同时承载编译期求值、不可变绑定与只读视图三种含义时规范与实现的每一处引用都会成为歧义的扩散点。提案通过收窄 generic type、细化 constant 为 compile-time constants、引入 compile-time binding 统称三项关键动作配合从 parameters 转向 bindings的表述迁移建立了一套与表达阶段体系严格对齐的术语矩阵。这些决议不仅同步写入了 design/README.md、Generics terminology 与 Member access expressions 三份核心设计文档也以SymbolicConstant、compile_time_binding_stack_、SymbolicBinding等标识符的形式沉淀进了 SemIR 常量管理 与 作用域检查 的实现中。对 Carbon 语言的设计者、编译器开发者与文档读者而言这套术语既是阅读规范的钥匙也是理解工具链源码的索引。【免费下载链接】carbon-langCarbon Languages main repository: documents, design, implementation, and related tools. (NOTE: Carbon Language is experimental; see README)项目地址: https://gitcode.com/GitHub_Trending/ca/carbon-lang创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考