在计算机科学与编程语言理论的发展历程中,“高阶引用”(higher-order references)这一术语始终带有浓厚的学术色彩,且其含义随着时间和研究方向的演变而变得颇为复杂。理解什么是“高阶”的引用,远不止字面上的含义,更涉及到逻辑学、类型论以及程序语义学的深刻联系。本文尝试深入剖析“高阶引用”中的“高阶”究竟指什么,同时梳理该术语的发展历史和不同语境下的用法差异,为计算机科学爱好者和专业人士提供一个清晰且系统的认知框架。首先需要明确的是,术语“高阶”本身源自逻辑学。高阶逻辑对应于逻辑表达式中量词所泛化的对象层次。从零阶逻辑到一阶、二阶乃至更高阶,关键在于量词能够面向的对象范围的提升。
零阶逻辑没有量词,仅涉及具体个体;一阶逻辑允许量词针对个体;二阶逻辑扩展到针对个体性质或集合的量化;三阶及更高阶逻辑则依此类推,针对更高层次的函数或谓词进行量化。类比到编程语言和类型系统,零阶值一般指基础类型值,例如整数、布尔值等不包含任何函数或引用的“基元”值。第一阶值则是能够接受或操作零阶值的函数,第二阶值则是操作第一阶函数的函数,依次递进。基于此逻辑,定义“高阶函数”就是可以接受或返回其他函数的函数。同理,“高阶引用”的定义也基于它指向的内容的层级。如果遵循这一思路,单纯指向基元值(零阶值)的引用属于第一阶引用,因为它量化的对象是零阶值。
如果引用本身指向的是其他引用,这便被认为是更高阶的引用,是对引用的引用,形成了递归层次。回顾历史文献可见,最初对“高阶引用”概念的使用是更直接且严格遵从这一层级含义的。1970年代末期的相关研究中,“高阶引用”多用来表示“指向引用的引用”,即多层嵌套的引用结构。当时的语义研究也由此引发了复杂而有趣的挑战,包括对递归引用的内存模型和行为的分析。然而,随着计算机科学领域的发展,尤其是1980年代末至1990年代初,新的使用习惯逐渐成形。特别是在1998年Abramsky及其合作者的工作中,“高阶引用”开始用来指称包含“高阶函数”的引用,即引用中存储的值本身是可以调用并产生副作用(如修改状态或内存)的函数。
这种用法在表面看来偏离了以量化层次区分引用阶层的传统定义,而更强调所引用值的性质——尤其是其高阶且带有副作用的函数属性。事实上,这种变革不仅仅是用词上的差异,更体现了研究关注重点的迁移——从引用结构的层级关系转向引用内容的表达能力和复杂行为。与此同时,为了避免术语上的混淆,学界还发展出了“通用引用”(general references)这样更宽泛的表述,涵盖能够存储基元值、高阶函数、引用自身以及递归和存在型类型等多样类型的引用。尽管该术语未能彻底解决“高阶引用”概念的多义问题,但至少承载了更多维度上的指代,使得相关研究更加包容和灵活。值得注意的是,“第一阶引用”这一表达在不同文献中也存在含糊。部分文献中它被用来指代只存储零阶值的引用,强调引用本身量化的对象是基元数据,从而区分于存储高阶函数的“高阶引用”。
这种对比使得“第一阶”和“高阶”在“引用”的语境下,指向了两个截然不同却又密切相关的维度:一个是引用层次结构,另一个是引用内容的类型阶层。更具挑战性的还有如何以精准且便于表达的词汇来指代那些专门存储高阶函数(尤其是带有副作用的函数)的引用。部分研究人员提出诸如“高阶值引用”(higher-order value references,简称HOVR)或“高阶函数引用”(higher-order function references,简称HOFR)等新词,试图在传统语义定义和实践应用需求之间架起一座桥梁。然而,这类词汇往往因生硬或重复过长而未被广泛采用,且因已有名词沿用历史较长,也难以完全替代以往用法。从整体上看,“高阶引用”作为计算机科学和程序语言概念中的一个热门主题,体现了理论和实践之间的动态张力。从严谨定义的角度,“高阶”意味着引用的引用链条层级;而从实际代码语义分析的角度,“高阶”更侧重于所持函数的复杂性和表达能力,尤其是影响程序状态的能力。
这两种定义的并存,不仅反映了学者之间在语言表达的多样性,也指出了设计和理解程序语言类型系统以及语义模型时必须面对的深层次问题。理解这一点对于编程语言设计者、编译器开发者、理论计算机科学家乃至高级程序员来说尤为重要。它帮助厘清语言中引用语义的复杂交互,特别是在涉及函数作为值、可变状态、闭包及递归引用等高级特性的设计和实现上,提供了理论指导和实践启示。未来,随着对程序语义理解的不断深化和新型编程范式的出现,“高阶引用”这一概念或许还将继续进化,语义范围会不断拓展,术语上的表述也会更加精准和丰富。倡导在学术和工程领域中,对术语用法保持敏感和开放,对促进理论理解和技术创新无疑是大有裨益的。综上所述,“高阶引用”一词的“高阶”之意存在多重理解路径。
一方面起源于高阶逻辑中的层级量化概念,指引用指向引用的递归层次;另一方面,更多现代语境下的“高阶引用”强调引用内容是能引发状态变化的高阶函数。认识并区分这两种用法是理解现代程序语言理论中引用行为复杂性和丰富性的关键一步,也是深入探究程序语义结构不可或缺的基石。