许多语言都有自省和反思的能力。然而,有些人显然比其他人更好。关于哪种语言在这方面"更好"的建议,以及为什么。
反射本质上是提取源程序的属性(或描述事实)的能力。为了能够检查关于源代码的任意属性(例如,任何和所有),需要您有可用的源代码来检查,或者至少有一些等效的源代码。
允许运行时反射的语言预先确定了可以检查哪些属性;数量和结果细节由语言设计者决定。因为提供反射需要花费运行时空间和时间,所以实际上所有这些语言都对可以反射/检查的内容有(特定于语言的)限制,因为它们都不愿意完整地保留源代码。因此,它们反映了语言设计者认为可能有用的东西,以及相对容易计算和紧凑存储的东西。这些限制对于编译语言来说尤其强烈,因为编译语言的目标是在执行和资源上更高效(与解释器相反)。
因此,您通常不能反映和获取有关注释的信息,或者有关特定变量可能包含的值范围的信息。
LISP是提供了大量反射能力的语言之一。这是因为LISP程序源文本在设计上与LISP列表是同构的,这是LISP存储程序代码的方式,至少在解释时是这样。LISP提供了对所有这些列表的直接访问,因此LISP程序可以直接检查它们自己的代码。[许多lisp允许编译;因此,一种语言的自省/反思能力在实践中总是有限的。
如果您想完全访问源文本的任意属性,则需要将移出语言,以便可以直接检查完整的源代码。
程序转换系统(PTS)是最接近这一点的工具。PTSs通常将源代码解析为抽象语法树,这是源代码的直接反映,因此可以充当等效的替身。更好的代码实际上保留了关于空白的注释和信息。然后可以使用一些 PTS编写自定义的任意算法,以爬过ast并从这些ast中提取任意信息。
使用PTS的一个非常好的副作用是,在检查了代码之后,PTS还可以转换代码或生成额外的代码来帮助解决驱动反射需求的问题。也就是说,分析问题或机会,并最终改进计划。
也许理想的语言是一种内置了完整PTS的语言。(我公司的DMS产品PTS,是一个小型的具有这种特性的协作DMS集合,我们经常使用DMS对自身进行永久性的检查/改造和提升。通常我们在检查/转换其他语言中使用DMS。