泛化函数

电脑编程中,泛化函数(generic function)或译泛型函数,是为多态而定义的函数。

在静态类型语言中

在静态类型语言(比如C++Java)中,术语“泛型函数”,指称一种叫做泛型编程的编译时间多态机制(静态分派英语Static dispatch),特别是参数多态。它们是使用类型参数英语TypeParameter定义的函数,意图用编译时间类型资讯来解决它。编译器使用这些类型来实例化适合的版本,适当的解决任何函数重载

在Common Lisp对象系统中

在某些面向对象编程系统,比如Common Lisp对象系统(CLOS)[1]Dylan中,泛化函数是一个实体,由具有相同名字的所有方法组成。泛化函数典型的是从functionstandard-object二者继承而来的类的实例。因此泛化函数是函数(可以被调用而应至实际参数)和正常对象二者。图书《元对象协议的艺术英语The Art of the Metaobject Protocol》详细解释了CLOS泛化函数的实现和使用。

Lisp的早期面向对象编程扩展是Flavors英语Flavors (programming language)[2]。它受Smalltalk影响,而使用平常的消息发送范型。发送一个消息的Flavors语法是:

 (send object :message)

对于New Flavors[3],它决定message应当是真正的函数,并使用常规函数调用语法:

 (message object)

message现在是泛化函数,是一个对象并且自身就是函数。message的个体实现叫做方法。

相同的想法实现于CommonLoops英语CommonLoops之中[4]。New Flavors和CommonLoops,是Common Lisp对象系统的主要影响者。

例子

Common Lisp

下面在SBCL中定义一个泛化函数,有两个形式参数object-1object-2。这个泛化函数的名字是collide

(defgeneric collide (object-1 object-2))

属于这个泛化函数的方法定义在类之外。这里为泛化函数collide定义一个方法,它特定于类asteroid(第一个形式参数object-1)和类spaceship(第二个形式参数object-2)。形式参数在方法体内作为正常变量使用。没有访问类槽的特殊命名空间:

(defclass asteroid () ())
(defclass spaceship () ())
(defmethod collide ((object-1 asteroid) (object-2 spaceship))
  (format t "asteroid ~a collides with spaceship ~a" object-1 object-2))

调用泛化函数:

* (collide (make-instance 'asteroid) (make-instance 'spaceship))
asteroid #<ASTEROID {1001959923}> collides with spaceship #<SPACESHIP {1001959963}>
NIL

Common Lisp还可以检索一个泛化函数的个体方法。FIND-METHOD从泛化函数collide找到特定于类asteroidspaceship的方法。

* (find-method #'collide nil (list (find-class 'asteroid) (find-class 'spaceship)))
#<STANDARD-METHOD COMMON-LISP-USER::COLLIDE (ASTEROID SPACESHIP) {1001939333}>

比较于其他语言

泛化函数粗略的对应于Smalltalk术语方法,但具有显著的例外,在Smalltalk的单一分派中,接收者的类,是调用哪个代码体的唯一确定者,与实际参数的类型或值无关。在具有多分派的编程语言中,在调用一个泛化函数的时候,方法分派在所有实际参数的基础之上发生,不只是有特权的那个实际参数。New Flavors英语Flavors (programming language)也提供了泛化函数,但只有单一分派。

引用

  1. ^ The Common Lisp Object System: An Overview (PDF). [2021-03-27]. (原始内容存档 (PDF)于2021-03-24). 
  2. ^ Howard Cannon, Flavors: A non-hierarchical approach to object-oriented programming页面存档备份,存于互联网档案馆), Symbolics Inc., 1982
  3. ^ David A. Moon英语David A. Moon, S Keene. New Flavors. Proceedings of ACM Conf. Object-Oriented Programming, Systems (ACM 1986 OOPSLA Conference). 1986. 
  4. ^ CommonLoops, Merging Lisp and Object-Oriented Programming (PDF). [2009-12-10]. (原始内容 (PDF)存档于2011-06-04).