Jump to content

Talk:Curiously recurring template pattern

Page contents not supported in other languages.
From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by 74.104.131.76 (talk) at 02:21, 2 January 2007 (There's a Java version, too). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
WikiProject iconC/C++ Unassessed
WikiProject iconThis article is within the scope of WikiProject C/C++, a collaborative effort to improve the coverage of C and C++ topics on Wikipedia. If you would like to participate, please visit the project page, where you can join the discussion and see a list of open tasks.
???This article has not yet received a rating on Wikipedia's content assessment scale.
???This article has not yet received a rating on the importance scale.

There's a Java version, too

Since Java 1.5 introduced its own implementation of generics, I've noticed a "curiously recurring generics pattern" in Java, but generally geared toward a somewhat different purpose:

 public interface Base<D extends Base<D>> {
     public D someOperation ();
     public D somethingElse (D argument);
     public void doSomethingWith (D whatever);
 }

It's even more common with abstract classes that provide a skeleton implementation, e.g.

 public abstract class Vector<D extends Vector<D>> {
     public abstract int getDimensions();
     private void checkDimensions (D other) {
         if (getDimensions() != other.getDimensions()) throw new Exception();
     }
     public D add (D other) {
         checkDimensions(other);
         return addImpl (other);
     }
     public D subtract (D other) {
         checkDimensions(other);
         return addImpl(other.negated());
     }
     public abstract D addImpl (D other);
     public abstract D negated ();
 }

where subclasses just override addImpl (and don't have to do dimension-mismatch detection) and implement negation. The use of the derived type as a parameter for the base type allows several Vector classes to share this code (don't repeat yourself is observed for things they can all do in a common way) while still accepting and returning themselves instead of some abstract type. Prior to Java 5, the pattern couldn't be used and all Vector subclasses would have to return a generic Vector and cope with a generic Vector parameter. So a Vector that was actually a polynomial function, FFT object, or whatever and another that was a plain old coordinate vector could be added with only a run-time ClassCastException to indicate there was a problem, and callers had to cast the return values. Java 5's covariant return types address the latter problem and its generics, coupled with the curiously recurring generics pattern, address the former problem.

(Polynomials, FFTs, and coordinate vectors can, mind you, be abstracted as having an array of components, perhaps in a java.util.Vector, of some length, added componentwise, but the example base class above is superior if you want addable, negatable things that don't have components -- either they don't decompose easily or naturally or they're actually the scalars used to build coordinate vectors -- or sparse representations etc.; FFTs *must* have a sparse representation of some sort, since you can't store the infinitely many coordinates needed for every sub and superharmonic of the fundamental.)