关于什么算是 PL 中的类型,我另外举几个跟这吧主题比较相关的例子。 在 ISO C 中, lvalueness 在 spec 的意义上是一种和 type 无关的 semantic property (同时在特定的上下文中因为在 Constraint 出现,为实现其检查可以弱化为 syntactic property ),但这并不妨碍一个和 ISO C 等价的形式语义把 lvalueness 通盘当作 type 来处理,就算它不是 ISO C 定义的 type 。类似地, ISO C++ 的 value category 以及 Rust 的 placement/value 的划分也具有相同的特征。 理由是,这些特性完美地符合静态类型需要的“类型”的普遍要求: statc & following terms 。 而且,一定程度上讲,就算强行只管静态类型,C 的 lvalueness 和 C++ 的 value category 是比这些语言的 spec 中明确定义的所谓 type 更有资格作为类型的 PL 意义上的类型。 实际上, C 和 C++ 的所谓 type 比上述的类型更复杂。例如 ISO C99 开始为了补全之前语义漏洞明确的 effective type ,以及 C++ 所谓的 dynamic type ,这些都不是“静态”的类型(反正 Robert Harper 看来无视这些了)。而反过来,lvalueness 和 value category 是要求在 translation phase 7 之前确定而彻底静态的。 当然,这不表示不能把这些东西搞成 latent 的。我的语言实现里就包含了这些东西(虽然我不想引入这些破烂但是要排除 GC 又不想搞更屑的 refinement type 之类,原则上无法避免),最近加上了类似 rvalue reference 而让类似 std::forward 的屑更麻烦了……因为类似 C++ 的 decltype() 和 decltype(()) ,实际上 object type 和 expression type 是两回事——而后者才是传统静态类型鼓吹者所谓的静态类型的来源。