可扩展编程(Extensible programming)是电脑科学的词语,是指程式设计的风格会着重在可以扩展编程语言编译器运行时系统的相关机制。可扩展编程语言(Extensible programming languages)是可以支持这种程式设计方式的编程语言,在1960年代曾是热门研究主题,而此运动在1970年代就已边缘化[1],在21世纪时此一主题又受到关注[2]

以往的发展

编辑

第一篇和可扩展编程运动有关的论文[1][3]道格拉斯·麦克罗伊在1960撰写,有关高级编程语言的论文[4]。另一个早期对可扩展原则的说明,出现在Brooker和Morris所著,有关编译器编译程序(compiler-compiler)的论文[5]。此运动中有二个具代表性,分别在1969年及1971年举行的学术座谈会,是此运动发展最热的时期[6][7]。Thomas A. Standish在1975年发表对此运动的调查文章,在本质上属于事后的剖析[1]Forth算是此一运动的例外,不过也没有被人注意到。

特点

编辑

可扩展编程语言会包括提供基础计算功能的基础语言(base language),以及可以修改基础语言的元语言。程序会包括元语言所进行的修改,以及以修改后基础语言所撰写的代码。

在此波潮流中,最著名的语言扩展技术就是宏定义。语法修改也和可扩展编程运动有密切的关系,最终发展成适应型文法英语Adaptive grammar形式主义Lisp编程语言的群体仍和可扩展编程语言群体分开,其原因显然如下:

任何编程语言,只要代码和资料在本质上可以互换,就可以视为是可扩展编程语言...由Lisp已长久当作可扩展编程语言来使用,就可以轻易的看出此一事实。[8]

在1969的研讨会中,认为Simula是可扩展编程语言。

Standish描述了三类不同的语言扩展,称为paraphrase、orthophrase和metaphrase。(paraphrase和metaphrase原来是翻译上的术语)。

  • paraphrase(改写)会说明新功能如何用以前定义(或是将要定义)的事物来表示,以此定义新的功能。Standish的举例提到了宏定义、一般程序定义、语法扩展、资料定义、运算符定义以及控制结构的扩展。
  • Orthophrase在语言中加入一些基础语言无法达成的功能,例如在没有输出入指令的基础语言中加入输入及输出功能。因为此功能无法用此基础语言表示,因此一定要用其他的语言来定义。这些扩展功能对原语言来说就是Orthophrase。这对应现代的插件
  • Metaphrase会修改诠释表示式时所用的规则。这对应现代的反射式编程

以往发展的终止

编辑

Standish认为当时可扩展编程的失败是因为若程序有数层的扩展,在撰写时会格外困难。程序员可以在基础语言上加上第一层的宏。若要在此语言上加上第二层的扩展,后续的程式设计者需要熟悉基础语言,以及第一层的扩展。若要加上第三层的扩展,程式设计者需要熟悉基础语言、第一层扩展以及第二层扩展。取代可扩展编程运动的抽象化,其本意就是让程式设计者 不用接触低端的细节。

Standish虽然在1975年时将Simula归类为可扩展编程语言,但其研究似乎没有将比较新的,以抽象化为基础技术算在可扩展编程语言内(只是其中对可扩展的定义,使用了非常宽的定义,抽象化在技术上是在该定义范围内)。1978年有一份文献提到程序抽象化的历史,说明从电脑发明以来的相关演进,其中没有提到宏,也没有提及可扩展编程运动[9]。一直到1980年代末期,才试验性的将宏列在抽象化运动中(可能是因为卫生宏的出现),其名称为“句法抽象化”(syntactic abstraction)[10]

现代的发展

编辑

现代支持可扩展编程的系统需要提供以下的所有功能[来源请求]

可扩展的语法

编辑

这是指所编辑的来源编程语言不能是封闭、固定、静态不能变化的。要支持在来源编程语言加入新关键字、新概念或是结构的功能。有些编程语言可以用用户定义语法加入组成元素,例如Coq[11]RacketCamlp4英语Camlp4、OpenC++、Seed7英语Seed7[12]Red英语Red (programming language)Rebol及Felix。可扩展的语法可以接受一些基础以及固有的编程语言特性是不变的,但系统不可能只依赖这些编程语言的功能,需可以加入新的编程语言功能。

可扩展的编译器

编辑

在可扩展编程中的编译器,不是一个将程序原始码转换为二进制可执行输出的单层系统。编译器本身也要是可扩展的,编译器在实质上是许多插件的组合,这些插件可以将原始编程语言的输入转换为任何想要的输出。例如,可扩展的编译器可以支持产生目标代码、程序文件、重新调整格式的原始码,或是其他想要的输出。编译器的架构需允许用户进入其编译流程内,在编译流程的各步骤可以提供其他的处理任务。

若考虑将原始程码翻译成电脑可以可执行文件案的这个任务,可扩展编译器需要有:

  • 在其功能的绝大部分层面,使用插件或是组件架构。
  • 确认要编译的语言(或是语言变体),配置适当的插件来的辨认及确认其语言。
  • 依各来源语言的型式语言规范,在句法及结构上确认。
  • 调用适当的确认插件,以协助来源语言的语义确认
  • 允许用户者在不同种类的代码产生器中选择,可以依处理器、操作系统、虚拟机及其他作业环境的不同,生成适合的可执行文件。
  • 提供错误消息产生的功能,以及相关的扩展。
  • 可以在抽象语法树(AST)中加入新的节点种类。
  • 抽象语法树的节点中允许有新的值。
  • 允许其他种类,连接节点的边。
  • 允许输入抽象语法树的转换,可以部分或全部来自外部的程序。
  • 允许输入抽象语法树的翻译,可以部分或全部交由外部的程序。
  • 协助内部和外部程序之间的资讯流,因为他们都会将抽象语法树转换或是翻译为其他的抽象语法树,或是其他表现方式。

可扩展的执行时环境

编辑

可扩展程序系统在执行时的环境要允许编程语言增加可处理的运算。例如,某个使用字节码解释器的系统,需要允许定义新的字节码。在可扩展语法下,可以接受少数基础运算或是固有运算是不能变的,不过这些固有运算要可以重载或是扩展,以便支持新增的行为。

内容和形式分离

编辑

可扩展程序系统需将程序视为要处理的资料。程序中需要完全没有格式化相关的资讯。要给用户的程序 视觉显示以及编辑都应该是可扩展编译器所支持的翻译函数,将程序资料转换成适合显示或是编辑的格式。此翻译会是双向的翻译。双向翻译的特性很重要,因为需要可以用许多不同的方式,轻松的处理可扩展程序。若只能用来源语言来编辑及查看,然后就翻译成机器代码,无法再翻译成其他的格式,这是无法接受的。透过将来源输入和其处理(格式、存储、显示及编辑)的格式分离,可以对程序进行各种不同的处理。

支持用原始语言调试

编辑

可扩展程序系统需要可以用原始来源语言来进行调试,即使是程序在变成可执行档的过程有进行转换或是扩展也是一样。最为人知的是:不可以假设运行时资料只能用结构或是数组的方式显示。调试器(更准确的说法是“程序检查器”)需要让运行时资料以适合其来源语言的形式来呈现。例如,若编程语言支持业务过程或是工作流的数据结构,需要将数据结构用插件表示为流程图或是其他适合的型式。

相关的软件或编程语言

编辑

相关条目

编辑

参考资料

编辑
  1. ^ 1.0 1.1 1.2 Standish, Thomas A., "Extensibility in Programming Language Design", SIGPLAN Notices 10 no. 7 (July 1975), pp. 18–21.
  2. ^ Gregory V. Wilson, "Extensible Programming for the 21st Century页面存档备份,存于互联网档案馆)", ACM Queue 2 no. 9 (Dec/Jan 2004–2005).
  3. ^ Sammet, Jean E., Programming Languages: History and Fundamentals, Prentice-Hall, 1969, section III.7.2
  4. ^ McIlroy, M.D., "Macro Instruction Extensions of Compiler Languages", Communications of the ACM 3 no. 4 (April 1960), pp. 214–220.
  5. ^ Brooker, R.A. and Morris, D., "A General Translation Program for Phrase Structure Languages", Journal of the ACM 9 no. 1 (January 1962), pp. 1–10. The paper was received in 1960.
  6. ^ Christensen, C. and Shaw, C.J., eds., Proceedings of the Extensible Languages Symposium, SIGPLAN Notices 4 no. 8 (August 1969).
  7. ^ Schuman, S.A., ed., Proceedings of the International Symposium on Extensible Languages, SIGPLAN Notices 6 no. 12 (December 1971).
  8. ^ Harrison, M.C., in "Panel on the Concept of Extensibility", pp. 53–54 of the 1969 symposium.
  9. ^ Guarino, L.R., "The Evolution of Abstraction in Programming Languages[失效链接]", CMU-CS-78-120, Department of Computer Science, Carnegie-Mellon University, Pennsylvania, 22 May 1978.
  10. ^ Gabriel, Richard P., ed., "Draft Report on Requirements for a Common Prototyping System", SIGPLAN Notices 24 no. 3 (March 1989), pp. 93ff.
  11. ^ Syntax extensions and notation scopes – Coq 8.17.0 documentation. coq.inria.fr. [2023-05-25]. (原始内容存档于2023-12-12). 
  12. ^ Zingaro, Daniel, "Modern Extensible Languages页面存档备份,存于互联网档案馆)", SQRL Report 47 McMaster University (October 2007), page 16.