5

我最近对引用、具体化和反思感到困惑。有人可以对他们的关系和差异(如果有的话)提供一个很好的解释吗?

4

1 回答 1

5

报价

这可能是最简单的一个。考虑在 REPL 中键入以下内容时会发生什么:

(+ a 1)

REPL 代表 Read Eval Print Loop,所以首先它读入这个。这是一个列表,所以读完后我们有一个包含 3 个元素的列表: <the symbol "+"> <the symbol "a"> <the number 1 >

下一步是评估。在 Common Lisp 中评估列表涉及查找绑定到列表中第一项的函数(或宏)。由于 + 绑定到函数而不是宏,因此它会评估列表中的每个后续元素。数字对自己进行评估,“a”将评估它所绑定的任何内容。现在参数已被评估,函数“+”被调用并带有评估结果。

然后我们打印结果并循环回到读取步骤

所以这很好,但是如果我们想要一些东西,在评估时,最终会成为一个包含 <the symbol "+"> <the symbol "a"> <the number 1> 的 3 个元素的列表呢?解决这个问题的方法是引用。Lisp 通常有一种称为“引用”的特殊形式,它接受一个参数,结果就是那个参数,未计算。所以

(quote (+ a 1))

将评估该列表。作为一些语法糖,' 被视为与 (quote ) 相同,所以我们可以只写 '(+ a 1)。

物化

具体化是一个通用术语,大致意思是“使抽象概念具体化”。具体到编程,当某个东西被具体化时,它大致意味着你可以把它当作数据(或“一等对象”)。lisp 中的一个示例是函数,lambda 表达式使您能够创建一个具体的、一流的对象,该对象代表函数调用的抽象概念。另一个例子是 CLOS 类,它本身就是一个 CLOS 对象,代表一个类的抽象概念。

反射

在某种程度上,反思是物化的对立面。给定一些具体的东西,你想要一些关于它的抽象表示的信息。考虑一个 Common Lisp 包对象,它是包概念的具体化,它只是从符号名称到符号的映射。您可以使用 do-symbols 遍历包中的所有符号,从而在运行时获取该信息。

另外,还记得我说过 lambda 是函数的具体化吗?好吧,“function-lambda-expression”是对函数的反映。

元对象协议(MOP)是用类和对象做各种事情的半标准方式。除其他外,它允许对类和对象进行反射。

于 2012-10-12T04:05:46.630 回答