manpagez: man pages & more
info guile
Home | html | info | man
[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

8.6.3 Merging Generics

GOOPS generic functions and accessors often have short, generic names. For example, if a vector package provides an accessor for the X coordinate of a vector, that accessor may just be called x. It doesn’t need to be called, for example, vector:x, because GOOPS will work out, when it sees code like (x obj), that the vector-specific method of x should be called if obj is a vector.

That raises the question, though, of what happens when different packages define a generic function with the same name. Suppose we work with a graphical package which needs to use two independent vector packages for 2D and 3D vectors respectively. If both packages export x, what does the code using those packages end up with?

duplicate binding handlers explains how this is resolved for conflicting bindings in general. For generics, there is a special duplicates handler, merge-generics, which tells the module system to merge generic functions with the same name. Here is an example:

(define-module (math 2D-vectors)
  #:use-module (oop goops)
  #:export (x y ...))
		  
(define-module (math 3D-vectors)
  #:use-module (oop goops)
  #:export (x y z ...))

(define-module (my-module)
  #:use-module (oop goops)
  #:use-module (math 2D-vectors)
  #:use-module (math 3D-vectors)
  #:duplicates (merge-generics))

The generic function x in (my-module) will now incorporate all of the methods of x from both imported modules.

To be precise, there will now be three distinct generic functions named x: x in (math 2D-vectors), x in (math 3D-vectors), and x in (my-module); and these functions share their methods in an interesting and dynamic way.

To explain, let’s call the imported generic functions (in (math 2D-vectors) and (math 3D-vectors)) the ancestors, and the merged generic function (in (my-module)), the descendant. The general rule is that for any generic function G, the applicable methods are selected from the union of the methods of G’s descendant functions, the methods of G itself and the methods of G’s ancestor functions.

Thus ancestor functions effectively share methods with their descendants, and vice versa. In the example above, x in (math 2D-vectors) will share the methods of x in (my-module) and vice versa.(30) Sharing is dynamic, so adding another new method to a descendant implies adding it to that descendant’s ancestors too.


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

This document was generated on April 20, 2013 using texi2html 5.0.

© manpagez.com 2000-2024
Individual documents may contain additional copyright information.