在现代计算机编程中,我们习惯于使用“调用函数”这一术语,但你是否想过,为什么程序员们会用“调用”这样一个词汇来描述执行函数的过程?“调用”这一词不仅仅代表程序运行时控制流的转移,更承载着计算机语言发展的历史印记和文化内涵。本文将带你穿越计算机历史的长河,探寻“调用函数”这一表达的起源及其背后的深层含义。 程序设计中的“调用”概念,最初来自于对现实生活中“召唤”或“呼叫”的类比。我们往往会把打电话给朋友、叫仆人帮忙或者向图书管理员“调阅”某本书,作为形象的比喻。三种意象中,最接近计算机上下文的是“召唤”这一含义:即从一个“图书馆”式的子程序库中调用特定函数,就犹如图书馆员根据“索书号”把特定书籍递交给读者一样。 实际上,英语单词“call”最早与图书馆相关的用法体现在“call number”(索书号)一词上。
19世纪末美国图书馆学家梅尔维尔·杜威(Melvil Dewey)便提出过“call number”的概念,指用以定位闭架书库中特定图书的独特编号。这一编号系统不仅方便了图书的查找,也为“call”一词后来在计算机领域的采用埋下了伏笔。 早期计算机编程中,子程序库的管理类似图书馆的藏书系统。用户需要“调用”某个功能模块时,程序会通过类似索书号的唯一识别码找到对应的代码段,并暂时转移控制权到该子程序执行。当执行完毕后,控制权再返回主程序继续运行。此时,“调用”既体现了对特定代码的“召唤”,也包含了控制流的临时转移。
可以追溯到1947年,计算机先驱约翰·莫克利(John W. Mauchly)在其关于EDVAC计算机的论文中,虽未频繁使用“call”一词,却描述了“从子程序库中调取和执行特定功能”的概念。当时子程序尚处于物理存储介质(如磁带或纸带)中,需要“调用”者通过编号或标记将其加载到内存中执行。此时的“调用”更接近于“取用”或“召唤”的动作,而非后来的运行时术语。 1950年代中期,随着计算机语言的发展,调用函数的概念逐渐演变得更加规范。以曼尼亚克二号(MANIAC II)计算机为例,它的汇编例程中便采用了“call number”作为子程序的唯一标识,程序通过“传输控制”(transfer control)的指令“TC”跳转至对应子程序,而“调用”则是汇编时将子程序“调用”到程序中的过程。这里的“调用”不仅仅是运行时操作,也涉及到组装和链接等编译阶段的管理。
1958年,Fortran II中首次引入了显式的CALL语句,程序员可以用CALL语句将控制权转移至指定的子程序,并传递参数。这一设计是“调用”概念的重大飞跃,它不仅是技术实现上的进步,也是语言表达上对“调用”动作的明确规范。Fortran的CALL语句所使用的英文“call”一词,直接体现了程序员“呼唤”函数执行的意图,进一步确立了“call”作为编程术语的地位。 紧跟其后,Algol 60和JOVIAL等语言也纷纷接受并传播了“调用”一词,赋予其程序运行时控制转移的完整含义。不同于早期仅仅作为物理调用和装载的意思,后期“调用”更多强调运行时环境中代码的暂时入口与出口,以及参数传递和返回值的处理。到了1960年代初,软件开发领域普遍使用“call”作为描述子程序执行的标准用语,形成了现代编程语言中函数调用的惯用表达。
值得注意的是,“调用”这一表达的传播,不只是技术发展的必然结果,也受到计算机科学者对日常生活语言的借用和重塑。程序员们将复杂的控制流程和代码管理用“call”来沟通,便于理解和教学,也加深了这一术语的根基。正如我们“呼叫”朋友或“召唤”仆人一样,程序中的“调用”体现了人类对信息访问行为的类比思考。 综上所述,现代编程中“调用函数”一词的出现,融合了图书馆学的索书号概念、早期计算机子程序库的“召唤”实践,以及计算机语言自身形态的演变,最终形成了现在我们熟悉的技术术语体系。理解这一历史渊源,不仅有助于我们更准确地掌握编程语言的语义,还能加深对计算机文化的理解,让每一次“调用”都赋予更多意义。