本页使用了标题或全文手工转换

Common Lisp对象系统

维基百科,自由的百科全书
跳到导航 跳到搜索
在ANSI common lisp中的标准方法组合

Common Lisp对象系统CLOS)是一种面向对象编程设施,它是ANSI Common Lisp的一部份。CLOS是强力的动态对象系统,在根本上不同于静态语言比如C++Java中的那种OOP设施。CLOS受到更早期的Lisp对象系统比如MIT Flavors英语Flavors (programming language)CommonLoops英语CommonLoops的启发,然而它比二者要更加泛化。最初被提议作为一种附加件,CLOS被接受为ANSI标准Common Lisp的一部份,并且已经被适配入其他Lisp方言比如EuLisp英语EuLispEmacs Lisp之中[1]

特征[编辑]

CLOS的基本建造块是方法、类的实例和泛化函数。CLOS提供了定义它们的宏:defclassdefmethoddefgeneric。CLOS不是基于原型语言,类必须声明于对象可以实例化为这个类的成员之前。实例通过方法make-instance来创建。

[编辑]

类可以有多个超类,一个槽(C++/Java用语中的成员变量)的列表和一个特定的元类。槽可以由类(一个类的所有实例共享这个槽)或实例来分配。每个槽都有一个名字,而一个槽的值可以使用函数slot-value通过这个名字来访问。可以定义额外的特定泛化函数来写或读这些槽的值。在CLOS类中的每个槽都必须有一个唯一的名字。

如同多数动态语言中的OO系统那样,CLOS不强制封装。任何槽都可以使用slot-value函数或通过(可选的自动生成的)访问子方法来访问。要通过slot-value进行访问就要知道这个槽的名字。CL编程者使用这个语言的设施来声明哪些函数或数据结构意图被导出。

CLOS允许多重继承。在多重继承中方法执行的缺省次序不正确的时候,编程者可以通过指定方法组合的次序来解决这种菱形继承问题英语diamond problem圆–椭圆问题英语Circle-ellipse problem在CLOS中已经解决,而多数OOP设计模式要么消失要么在性质上更加简单了[2]

CLOS是动态的,意味着不只是内容,它的对象的“结构”也可以在运行时间修改。CLOS支持现场(on-the-fly)变更类定义(即使正在考虑的这个类的实例已经存在),还有通过change-class算子变更一个给定实例的类成员关系。CLOS还允许在运行时间增加、重新定义和移除方法。

多分派[编辑]

CLOS是一个多分派系统。这意味着方法可以依据它们所要求的任何或所有实际参数来指定。多数OO语言是单分派的,意味着方法只能依据第一个实际参数来指定。其他不常见特征是方法不“属于”类;类不为泛化函数或方法提供命名空间。方法是独立于类而定义的,并且它们对类的槽没有特殊的访问(比如thisselfprotected)。

在CLOS中的方法被组织入泛化函数。泛化函数是像函数一样可调用的一个对象,它关联着有共享的名字和参数结构的方法的一个搜集,其中每个都特定于不同的实际参数。因为Common Lisp为结构和内建数据类型(数值、字符串、字符、符号等)提供了非CLOS类,CLOS分派也工作在这些非CLOS类之上。CLOS还支持在个体对象(eql specializer)上的分派。CLOS缺省的不支持在所有Common Lisp数据类型上的分派(比如分派不工作于完全特殊化数组类型或通过deftype介入的类型)。然而多数Common Lisp实现提供了元对象协议,它允许泛化函数提供特定于应用的特殊化和分派规则。

方法组合[编辑]

在CLOS中的分派还不同于多数OO语言:

  1. 给出一个实际参数列表,确定一个可应用的方法的列表。
  2. 这个列表依据它们的形式参数的特殊化器(specializer)的特殊性(specificity)来排序。
  3. 接着使用泛化函数所用的那个方法组合,将从这个列表选择出的那些方法组合成一个有效方法。
  4. 接着用最初的实际参数调用这个有效方法。

这个分派机制工作在运行时间。增加或移除方法将导致在运行时间变更有效方法(即使在用相同的实际参数调用泛化函数的时候)。变更方法组合还导致不同的有效方法。

例如:

; 声明共同的实际参数结构原型
(defgeneric f (x y))

; 定义对(f integer t)的实现,这里的t匹配所有类型
(defmethod f ((x integer) y) 1)

(f 1 2.0) => 1

; 定义对(f integer real)的实现
(defmethod f ((x integer) (y real)) 2)

(f 1 2.0) => 2 ; 分派发生在运行时间

除了常规(“主要”)方法之外,还有:before:after:around这些“辅助”方法。前两个方法按照基于类层级的特定次序,分别先于或后于主要方法而调用。:around方法可能控制主要方法是否执行。此外,编程者可以指定沿着类层级的所有可能的主要方法,是都应当被调用还是只调用提供最接近匹配的那个方法。

“标准方法组合”提供上述的主要、之前、之后和围绕方法。还有具有其他方法类型的其他方法组合。可以定义新的(简单和复杂二者)方法组合和方法类型。

元对象协议[编辑]

在ANSI Common Lisp标准之外,有一个对CLOS的广泛实现的扩展,叫做元对象协议(MOP)。MOP定义到CLOS实现的基础支撑的标准接口,将类、槽描述、泛化函数和方法自身处理为元类实例,并允许定义新的元类并修改所有CLOS行为。CLOS MOP的灵活性预示了面向切面编程,它是由同一群工程师比如Gregor Kiczales英语Gregor Kiczales开发的。MOP通过一组协议定义了整个对象系统的行为。这些定义是依据CLOS定义的。因此有可能通过扩展或变更已提供的CLOS系统的功能来建立新的对象系统。图书《元对象协议的艺术英语The Art of the Metaobject Protocol》描述了CLOS MOP的使用和实现。

各种Common Lisp实现对元对象协议有稍微不同的支持。Closer计划致力于提供缺失的特征[3]

来自更早的基于Lisp的对象系统的影响[编辑]

Flavor英语Flavors (programming language)(和它的后继者New Flavors)是MIT Lisp机器上的对象系统。Lisp机器操作系统的很大部份和它的很多应用使用了Flavors或New Flavors。 Flavors介入了多重继承mixin和其他一些特征。Flavors几乎废止了,尽管存在针对Common Lisp实现。Flavors使用消息传递范型。New Flavors介入了泛化函数。

CommonLoops英语CommonLoops是LOOPS的后继者(它来自Xerox Interlisp英语Interlisp-D)。CommonLoops是针对Common Lisp的实现。叫做可移植CommonLoops(PCL)的可移植实现是第一个CLOS实现。PCL被广泛的移植了,并仍为很多Common Lisp实现提供CLOS实现的基础。PCL绝大部份以可移植的Common Lisp实现而只有很少的系统依赖部份。

其他语言中的CLOS[编辑]

由于CLOS的能力和表达力,还有历史上能获得的TinyCLOS(Gregor Kiczales英语Gregor Kiczales为用于Scheme而书写的简化的可移植的CLOS实现),类CLOS的基于MOP的对象系统成为大多数Lisp方言实现的事实规范,还能在一些其他语言的OOP设施中找到它:

引用[编辑]

  1. ^ "CLOS is a standard. Multiple vendors supply CLOS. CLOS (or parts of it) is being used to add object-orientation to other Lisp dialects such as EuLisp or Emacs Lisp." p. 110 of Veitch 1998
  2. ^ In the Design Patterns in Dynamic Languages slides, Peter Norvig presents his findings that 16 out of 23 design patterns taken from various textbooks are either "invisible or simpler" in Dylan or Common Lisp than in C++.
  3. ^ Closer Project: Closer to MOP
  4. ^ COOPS
  5. ^ COS, the C Object System
  6. ^ Dynace Object Oriented Extension To C
  7. ^ EIEIO
  8. ^ Gauche
  9. ^ GOOPS
  10. ^ Meroon
  11. ^ Sagittarius
  12. ^ sos
  13. ^ STklos
  14. ^ Swindle
  15. ^ Tiny CLOS, developed by Gregor Kiczales
  16. ^ VCLOS, CLOS for Skill
  • "CommonLoops: merging Lisp and object-oriented programming", by Daniel G. Bobrow, Kenneth Kahn, Gregor Kiczales, Larry Masinter, Mark Stefik, Frank Zdybel. 1986, Portland, Oregon, United States. Pages 17–29 of the Conference on Object-oriented Programming Systems Languages and Applications, ISSN 0362-1340.
  • "A History and Description of CLOS", by Jim Veitch. Pages 107–158 of Handbook of Programming Languages, Volume IV: Functional and Logic Programming Languages, ed. Peter H. Salus. 1998 (1st edition), Macmillan Technical Publishing; ISBN 1-57870-011-6

参考文献[编辑]