在我继续讨论一些我想添加另一个答案的事情之前,这里还有一个参考——与同像性相关的部分相当短,但由 Rich Hickey 进行解释! 9频道有这个不错的视频 http://channel9.msdn.com/shows/Going+Deep/Expert-to-Expert-Rich-Hickey-and-Brian-Beckman-Inside-Clojure/Rich Hickey 和 Brian Beckman 谈论 Clojure。可以理解的是,并发性是主要焦点,但同像性确实有自己的(短暂的)屏幕时间,在此期间,里奇很好地解释了两者之间的相互作用read
(将程序员写下的具体语法转换为从列表等构建的内部表示的函数)和eval
。他有这张漂亮的图表展示了如何eval
甚至不知道它评估的代码来自read
对文本文件进行操作...亚瑟已经解释了其背后的要点,但是嘿,无论如何请观看它,这是一个非常好的视频!
免责声明:我将在下一个水平条下方提及 Java 和 Python 作为示例。我想澄清的是,下面只是一个粗略的概述,说明为什么我认为制作一个同像的、支持 Lisp 风格的宏的 Java 或 Python 可能很困难;不过,这只是一项学术练习,我不想首先考虑是否有任何理由去尝试的问题。还,我不想暗示具有 Lisp 风格宏的语言的语法必须包含树结构的显式分隔符; Dylan(无父母 Lisp?)显然提供了一个反例。最后,我使用这个表达Lisp 风格的宏因为我只研究 Lisp 风格的宏。例如,Forth 语言有一个不同的宏工具,我并不真正理解它,只是我知道它可以启用看起来很酷的代码。显然,语法扩展可以通过多种方式实现。有了这个……
我想回答你问题的第二部分——为什么大多数编程语言被认为不是同像的?在这个过程中我将不得不触及 Lisp 的语义,但是由于 Nils 已经提供了关于术语“同像”本身的良好信息源的链接,并且 Arthur 描述了读取 -> 宏扩展 -> 编译循环,如图所示在 Clojure 中,我将在下文中以此为基础。首先,让我引用 Alan Kay 的一段话(摘自维基百科文章,该文章也链接到原始来源):
Interactive LISP [...] 和 TRAC [...] 都是“同象的”,因为它们的内部和外部表示本质上是相同的。
(这些[...]位隐藏了很多文本,但要点没有改变。)
现在,让我们问自己一个问题:Java 的内部表示是什么?……好吧,这甚至没有意义。爪哇compilerJava确实有一定的内部表示,即抽象语法树;为了构造一个“同形 Java”,我们必须使 AST 表示成为 Java 中的一等对象and设计一种允许我们直接编写 AST 的语法。这可能会被证明是相当困难的。
Python 提供了一个非同像语言的示例,该语言很有趣,因为它目前附带了一个 AST 操作工具包,其形式为ast
模块。该模块的文档明确指出 Python AST 可能会在版本之间发生变化,这可能会或可能不会令人沮丧;尽管如此,我认为勤奋的程序员可以接受ast
模块,设计一种语法(可能基于 S 表达式,可能基于 XML)来直接描述 Python AST,并使用常规 Python 为该语法构造一个解析器ast
,从而朝着创建具有 Python 语义的同像语言迈出了坚实的第一步。 (我相信不久前我遇到过一种 Lisp 方言编译为 Python 字节码......我想知道它是否可能在某种程度上做类似的事情?)
即便如此,从这种同像性中获取具体利益的问题仍然存在。它被视为 Lisp 语言家族成员的一项有益财产,因为它允许我们编写可以编写更多程序的程序,其中宏是最值得注意的。现在,虽然宏以一种方式启用,因为在 Lisp 中操作 Lisp 代码的内部表示非常容易,但它们也以同样重要的方式通过 Lisp 执行模型启用:Lisp 程序只是 Lisp 形式的集合;这些由 Lisp 函数处理eval
它负责确定表达式的值并在正确的时间引起适当的副作用; Lisp 的语义正是eval
。事物如何在内部工作以保持这种语义错觉同时相当快的问题是一个实现细节; Lisp 系统有义务公开一个函数eval
给程序员并采取行动as ifLisp 程序正在由该函数处理。
在现代 Lisp 系统中,它是eval
的合同,它执行一个额外的预处理阶段,在此期间宏在评估代码(或编译和运行,视情况而定)之前进行扩展。该特定设施并不是 Lisp 系统的必要部分,但将其插入此执行模型非常容易!另外,我想知道这是否不是唯一使 Lisp 类型的宏转换易于管理的执行模型,这意味着任何寻求合并 Lisp 风格宏的语言都必须采用类似的执行模型。我的直觉告诉我,事实确实如此。
当然,一旦一种语言以直接与其 AST 并行的符号写下来,并使用带有评估器函数/对象的类似 Lisp 的执行模型,人们一定想知道它是否是 Lisp 的另一种方言……即使它是AST 并行语法恰好是基于 XML 的。shudder