尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Carbon 泛型术语体系解析:从 “generics/templates“ 到 “checked generics/template generics“(提案 p002138)

Carbon 泛型术语体系解析:从 “generics/templates“ 到 “checked generics/template generics“(提案 p002138) Carbon 泛型术语体系解析从 generics/templates 到 checked generics/template generics提案 p002138【免费下载链接】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 仓库中的提案 p002138-checked-and-template-generic-terminology.md 展开系统梳理 Carbon 泛型generics术语体系的演进提案将原本含义模糊的 generics 与 templates 两个词重新定义为以 generics 为总称、以 checked generics 与 template generics 为两个分支的清晰术语树。读完本文你将掌握 Carbon 官方文档中 checked generic parameter、template generic parameter、generic parameter 等术语的确切含义与省略规则理解这一命名决策背后的动机、对 C 互操作目标的支撑以及备选方案被否决的具体理由并能结合 docs/design/generics/terminology.md 与 docs/design/generics/overview.md 中的语法示例准确阅读和书写 Carbon 泛型代码。背景与问题为什么需要重构泛型术语Carbon Language 在设计之初就面临一个术语上的尴尬它同时支持两种泛型机制——类似多数现代语言中受约束的泛型以及类似 C 模板的模板机制。在提案撰写时官方文档中的用词是 generics泛指受约束的泛型和 templates指模板二者被当作并列概念对待。这个命名方式存在两个实际问题社区心智模型错位C 社区普遍通过模板templates来做泛型编程generic programming因此 C 开发者天然认为模板是实现泛型的一种机制。在 Carbon 中模板与其他泛型特性的相似性远大于差异性如果术语上把二者割裂成两个平级概念就无法找到一个简洁的方式统称既适用于模板又适用于受约束泛型的事物。沟通成本高由于 Carbon 的两种机制在很多场景下行为相近设计文档、讨论和代码评审中频繁需要同时提及二者缺少统一术语意味着每次都要写成 template or generic 这类冗长表达。正是为了解决这两个问题提案 p002138 提出了一次全局性的术语变更。提案核心建立 generics 总称下的双分支术语术语变更方案提案的 Abstract 与 Proposal 部分给出了一致的核心主张将术语从 generics 和 templates 变更为 checked generics 和 template generics。变更之后generics 将成为涵盖模板在内的伞形术语umbrella term。变更前后的对照关系可以概括为变更前变更后genericschecked genericstemplatestemplate generics无统称generics伞形术语包含 checked generics 与 template generics这一变更是自下而上、逐参数生效的而非针对整个函数或类型的一刀切。正如 docs/design/generics/terminology.md 明确指出的Carbon 在区分 checked 与 template generics 时是按参数逐个区分的——单个函数可以同时混用运行时参数、checked generic 参数和 template generic 参数。参数级别的术语对于参数提案给出了三组对应的术语checked generic parameter受约束泛型参数对应旧称 generic parameter 中偏向 checked 的那一类template generic parameter模板泛型参数对应旧称 template parametergeneric parameter作为伞形术语统称上述两类参数。提案还给出了一个实用的省略规则当上下文已经足够清晰时可以从这些术语中省略 generic 一词而这一省略对于 template parameter 而言通常是成立的。换句话说日常书写中 template parameter 依然是被接受的简化写法但完整形式 template generic parameter 更能体现模板泛型是泛型的一种这一语义。新旧术语在仓库文档中的对照提案点名了两个仓库文档作为新旧用法的对照样本docs/design/generics/overview.md该文档撰写于术语变更之前使用旧式 generics 与 templates 的表述例如其中SortVector示例通过generic关键字显式标注 checked generic 参数docs/design/README.md 的 Generics 章节该章节尤其是 Checked and template parameters 小节已经采用提案确立的新术语并将其与后续提案 p002200-template-generics 的语法决策衔接。这两份文档如今在仓库中并存恰好构成了观察术语演进过程的前镜像与后镜像。术语如何在语法与语义层面落地术语不是孤立的标签它直接映射到 Carbon 的具体语法和类型检查语义。以下是新术语体系在仓库设计文档中的完整落地。关键字与上下文默认值依据 docs/design/README.md 与 docs/design/generics/terminology.md三种参数通过三种 binding pattern 区分并使用runtime、generic、template三个关键字来覆盖上下文默认值运行时参数runtime parameters显式参数列表(...)与局部变量的默认类型可用runtime关键字在非默认上下文中显式标注checked generic 参数推导参数列表[...]以及interface、class等编译期实体参数的默认类型在显式参数列表(...)中需要用generic关键字显式标注template generic 参数通过在参数前加template关键字指定永远不会是默认值。此外还有一条一致性约束与上下文默认值匹配的关键字是不被允许的。例如在推导参数列表[]中写generic T: Comparable会与默认行为重复属于冗余写法关联常量associated constants则永远是 checked generic 绑定这一位置既无其他可选阶段也不允许出现任何阶段关键字。三种绑定模式从绑定模式binding patterns的角度看见 docs/design/generics/terminology.md术语对应如下runtime binding pattern绑定到运行时的动态值是显式函数参数的默认checked generic binding pattern绑定到符号常量symbolic constant——在类型检查时未知、但会在代码生成阶段单态化monomorphization时确定的编译期值是推导参数与编译期实体参数的默认也是关联常量的唯一允许形式template generic binding pattern绑定到模板常量template constant——在类型检查时就已知的编译期值通过template关键字标识使用这类绑定的表达式是依赖dependent表达式需要延迟到实例化提供绑定值之后进行晚期类型检查。代码示例新旧语法的对比docs/design/generics/overview.md 中的SortVector示例展示了使用generic关键字显式声明 checked generic 参数的写法fn SortInt32Vector(a: Vector(i32)*) { ... } fn SortStringVector(a: Vector(String)*) { ... } ... fn SortVector(generic T: Comparable, a: Vector(T)*) { ... }其中generic关键字表明参数T是一个 checked generic 参数若改为template关键字则声明的是一个 template generic 参数。当参数写在方括号推导列表[]中时checked 是默认值可以省略generic关键字如SortVectorDeducedfn SortVectorDeducedT: Comparable*) { ... } SortVectorDeduced(anIntVector); // T 被推导为 i32 SortVectorDeduced(aStringVector); // T 被推导为 String而在 docs/design/README.md 的Convert示例中T与U是混用 checked 默认与显式 template 的典型写法fn Converttemplate T: type - U { var converted: U source; return converted; } fn Foo(i: i32) - f32 { // T 的隐式参数为 i32U 的显式参数为 f32 return Convert(i, f32); }同一个函数里推导参数列表中的template T与显式参数列表中的template U均为 template generic 参数而 docs/design/README.md 中TemplatedMin则展示了带约束的模板参数——约束并非 checked 泛型的专利模板参数同样可以声明约束只是这种约束只影响调用方的重载解析与错误信息不参与定义体内部的类型检查fn TemplatedMintemplate T: Ordered - T { return if x y then x else y; }Checked 与 Template 的语义差异对照docs/design/generics/terminology.md 用一张对比表系统总结了两种参数的预期差异这正是新术语所要承载的语义边界Checkedchecked genericTemplatetemplate generic有界参数多态bounded parametric polymorphism编译期鸭子类型与 ad-hoc 多态受约束的泛型性constrained genericity可选约束定义可孤立解析名字查找早期名字查找可利用参数信息可能晚期定义可孤立完成类型检查早期完整类型检查可能依赖调用信息可能晚期支持分离式类型检查可能支持分离编译分离编译仅到 C 所支持的程度允许但不要求用动态分派实现不支持动态分派实现只能通过实例化静态实现单态化是可选的优化不会使程序失效单态化是强制的且可能失败导致程序非法这张表同时解释了 docs/design/generics/overview.md 中列出的 checked generics 优势的来源调用与函数体可分别依据函数签名独立检查、错误信息更早更清晰、构建更快尤其开发构建、同时支持静态与动态分派。支撑性概念定义检查、依赖名字与实例化新术语体系中的 checked 一词直接来源于定义检查definition checking能力见 docs/design/generics/terminology.md定义检查指在不依赖任何具体参数值的情况下独立地对参数化代码定义进行语义检查含类型检查的过程。即使是模板定义中不依赖任何模板参数的表达式也可以提前检查给模板参数添加约束、或将其切换为 checked都能提升定义可被提前检查的比例剩余检查则延迟到实例化阶段而实例化是可能失败的。**完整定义检查complete definition checking**是定义可被完整类型检查的性质它是分离式语义检查乃至分离编译的前提也是类型擦除type erasure、动态分派见证表witness table等不实例化实现的策略所必需的。**依赖名字dependent names**指依赖某个 checked 或 template 参数的名字其含义与 C 中的 dependent name 一致而非依赖类型dependent types。实例化instantiation是 C 与 Carbon 模板共用的实现策略显式复制模板代码并将模板组件替换为具体类型天然意味着模板代码会被复制且不同实例可能对同一结构做出不同解释模板中可以包含对某些实例非法的结构——这也解释了为什么模板错误可能直到实例化才暴露甚至只对部分实例暴露。术语变革的理由支撑项目目标提案在 Rationale 部分明确指出采用社区预期的术语直接支撑 Carbon 的两项项目目标见 docs/project/goals.mdCode that is easy to read, understand, and write用于解释代码的文档更易理解、更准确代码本身也因此更易读写Interoperability with and migration from existing C codeCarbon 与 C 之间的术语差距更小有利于 C 开发者迁移与两语言互操作。值得强调的是模板是泛型的一种这一认识并非只是措辞美化——它反映了 Carbon 中二者在语言机制上的真实亲缘关系模板泛型与 checked 泛型共享编译期参数化的本质二者的差异主要在于类型检查的时机与方式而非机制的根本不同。备选方案与取舍分析提案在 Alternatives considered 部分完整记录了三个被否决的备选方案这些讨论对理解最终选择非常有价值。方案一维持现状generic 专指 checked即保持 generic 指 checked generics、template 指 template generics需要统称时写 template or generic。优点generic 与 template 比 checked generic 与 template generic 更简洁template 对 C 背景的开发者更熟悉。缺点无法提供一个统一术语来统称模板与泛型而二者在 Carbon 中高度相似导致各种场合都需要反复并列提及不承认模板被用于泛型编程、因此是泛型的一种这一事实此外 Carbon 的模板泛型与 C 模板并不完全相同沿用旧称可能在个别情形下给 C 迁移者带来错误直觉。方案二用 templates 代替 template generics即 checked generic 指受约束泛型、template 指模板泛型、generic 统称二者。优点比提案用词更简洁对 C 开发者更熟悉并且人们本来也更倾向于说 template 而不是 template generics。缺点与 checked generics 不对称丢失了template generic 是泛型的一种这一含义同样存在 Carbon 模板与 C 模板不完全相同的误导风险。方案三用 unchecked generics 代替 template generics即 checked generic 与 unchecked generic 形成对偶用 generic 统称二者。该方案最初在 PR #1443 中被提出。优点与 checked generics 形成更好的平行对照描述的是语义而非实现策略——尤其考虑到模板化/单态化同样也是 unchecked generics 计划采用的实现策略。缺点对 C 开发者陌生需要重命名template关键字或为它另选非关键字语法否则会出现关键字与术语不一致的尴尬而且模板泛型并非完全不检查只是检查无法在参数值已知之前完成。最终提案选择了 checked generics 与 template generics 这对术语它在模板是泛型的一种这一语义上更准确与template关键字的现状兼容同时通过允许在上下文清晰时省略 generic 保留了日常书写的简洁性。术语体系的持续演进术语决策并非一锤定音。在 p002138 之后Carbon 的泛型语法经历了一次重要修订提案 p007254-replace-and-with-keywords-and-contextual-defaults.md 用runtime、generic、template关键字与上下文默认值取代了早先的:!与:?语法并在其 Alternatives 一节中再次讨论了 Usetemplate genericinstead of justtemplate 等选项见 docs/design/generics/terminology.md。如今docs/design/README.md 中的表达式阶段expression phases体系——template constant、symbolic constant、runtime value——与 p002138 确立的参数术语一一对应共同构成了 Carbon 泛型语义的完整词汇表。对希望深入阅读的读者建议按以下路径继续docs/design/generics/terminology.md完整术语表含 facet type、archetype、instantiation、coherence 等全部概念定义docs/design/generics/overview.md泛型设计总览与大量语法示例docs/design/generics/goals.mdchecked generics 的设计目标与模板的定位docs/design/README.md语言设计总览中的术语落地章节proposals/p002138-checked-and-template-generic-terminology.md本文所解析的原始提案。【免费下载链接】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),仅供参考
返回列表