同像性

科技工作者之家 2020-11-17

同像性是某些编程语言的基本特性,它意味着一个程序的结构与其句法是相似的,因此易于通过阅读程序来推测程序的内在涵义。

一门编程语言具备同像性,说明该语言的文本表示(通常指源代码)与其抽象语法树具有相同的结构(即AST和句法同构)。该特性使得代码可以被当作数据来修改或者变换,提供了“代码即数据”的理论前提。Lisp语言是典型的同像性语言。

简介在计算机编程中,同像性(homoiconicity,来自希腊语单词 homo,意为与符号含义表示相同)是某些编程语言的特殊属性,它意味着一个程序的结构与其句法是相似的,因此易于通过阅读程序来推测程序的内在涵义。如果一门编程语言具备了同像性,说明该语言的文本表示(通常指源代码)与其抽象语法树(AST)具有相同的结构(即,AST 和语法是同形的)。该特性允许使用相同的表示语法,将语言中的所有代码当成资料,来存取以及转换,提供了“代码即数据”的理论前提。

同像语言中,程序的主要呈现方式,也是语言本身原始类型中的数据结构。这使得元编程(metaprogramming)更加容易,因为程序代码可以被视为资料:语言中的反射(运行时检查程序的实体)取决于单一的、性质相同的结构,而且它不必去处理,其它一些不同结构所导致的复杂语法。换句话说,同像性是程序的源代码即是基本的数据结构,而这个语言本身知道如何存取源码的文本。

Lisp编程语言是具有同像性质的典型范例。它的设计很容易进行对列表的操作,而且其语法结构即采用嵌套列表形式的S-表达式。LISP 程式以列表的形式来编写; 所以可在运行时存取本身拥有的函数和程序,并以编程的方式重新设计自己。具有同像属性的语言通常有对句法宏的全面支持,允许程序员以简明的方式来表达程序的变换。这类语言有 Clojure(现代流行的 LISP 方言),Rebol 和 Refal,以及最近的 Julia 等等编程语言。1

历史同像性一词的原始来源是论文《编译器语言的宏指令扩展》。根据早期具影响力的论文《TRAC,文本处理语言》中提到: “主要设计目标之一是TRAC的输入脚本(用户所输入的)应该与指示TRAC处理器内部动作的文本相同一致。换句话说,TRAC程序应该是以字串被储存于内存中,正如同用户在键盘上键入它们一样。如果TRAC程序本身发展成为新的程序,同一个脚本中也应该陈述列出这些新程序。TRAC处理器在其操作中将此脚本直译为其程序。换句话说,TRAC解析器(处理器)有成效地将计算机转换为具有新程序语言(TRAC 语言)的新计算机。程序或过程资讯在任何时候的呈现,都应该相同于TRAC处理器执行期间对其作用的形式。我们期望内部代码的字符表示,和外部代码表示相同一致或非常相似。在本TRAC实作中内部字符立基于ASCII,因为TRAC程序和文本在处理器内部和外部都具有相同的表示,所以术语同像性一词是适用的,从涵义相同于符号呈现的意义。”

依照道格拉斯·麦克罗伊的提议,依据Peirce,C.S.McIlroy M.D.的术语,“编译器语言的宏指令扩展”,ACM通讯,页214-220; 1960年4月。

艾伦·凯在他1969年的博士论文中使用并可能推广了同像性这个术语: “所有先前的系统之外,显著的一组例外是Interactive LISP[...]和TRAC。两者都是函数导向的(一为列表,另一为字符串),都用一种语言与用户交谈,并且都具有 “同像性的”,因为它们内部和外部表示本质上相同。它们都具有动态创建新函数的能力,然后可随着用户的兴趣进阶发展。他们唯一最大的缺点是,以它们写出的程序看起来像是苏美人把Burniburiach国王的信写成巴比伦楔形文!”1

优缺点同像性的一个优点是,以新概念扩展语言通常变得更简单,因为表示代码的资料可在程序的元和基本层之间传递。函数的抽象语法树可以作为元层中的数据结构来组成和操作,然后被评估。它可以更容易理解如何操作代码,因为它可以被理解为简单的资料(语言本身的格式亦同为资料格式)。

允许这样做的简单性也带来了一个缺点:一个博客认为,至少在类似LISP的列表导向的语言的情况下,它会消除许多能帮助人们分析语言结构的视觉线索,而可能导致陡峭的学习曲线。1

本词条内容贡献者为:

王沛 - 副教授、副研究员 - 中国科学院工程热物理研究所

科技工作者之家

科技工作者之家APP是专注科技人才,知识分享与人才交流的服务平台。