Generics and the Mandelbrot set
Elaborating on [URL="http://blogs.sun.com/darcy/resource/JavaOne/J1_2008-BOF-5874.pdf"]some slides from a JavaOne talk[/URL], the [URL="http://en.wikipedia.org/wiki/Mandelbrot_set"]Mandelbrot set[/URL] is defined recursively as the set of values in the complex plane [I]C[/I] where the iterations zn+1 = zn2 + c remain bounded, giving rise to a familiar and complex shape.
[IMG]http://blogs.sun.com/darcy/resource/GenericsMandelbrot/mandelbrot_set.jpg[/IMG] Determining whether a particular point is inside or outside the boundary of the Mandelbrot set can be difficult because of the fractal nature of the curve; however, good approximations are possible. First at a coarse level, if the absolute value of a point is greater than 1, it is definitely [I]not[/I] part of the Mandelbrot set so all of the Mandelbrot set is contained within a circle of radius 2 centered at the origin. Second, there are two primary curves within the set:
[LIST] [*]A circle of radius ¼ centered at (-1, 0)
A heart-shaped [I][URL="http://en.wikipedia.org/wiki/Cardioid"]cardiord[/URL][/I] whose boundary is [I]c[/I] = [I]eit[/I]/2 - ([I]eit[/I]/2)2
[/LIST] The overall area of the Mandelbrot set is a bit over 1.5; the circle has area ≈0.1963, 13.0% of the total, and the cardiord has area ≈1.178, 78.1% of the total. Therefore, together the circle and cardiord contain over 90% of the area of the whole set and it is comparatively easy to determine if a point is inside or outside the union of the circle and the cardiord.
[IMG]http://blogs.sun.com/darcy/resource/GenericsMandelbrot/mandelbrot_approx.png[/IMG] Using generics in Java has some similarities to the Madelbrot set. Generics can be recursive, such as in the f-bound in the declaration of java.lang.Enum: public abstract class Enum..., and it can be trickly to determine if a use of generics is reasonable. Fortunately, another similarity is that there are two primary use-cases for generics that cover the vast majority of sensible scenarios:
[LIST] [*]Generic aggregates, List, Set, etc.
Type tokens, Class (or even [URL="http://gafter.blogspot.com/2006/12/super-type-tokens.html"]super type tokens[/URL])
[/LIST] Aggregates as found in java.util.Collections are the heart of generics usage and using generic collections is usually straightforward; [I]Effective Java[/I]'s PECS mnemonic (producer-extends, consumer super) provides guidance for some of the trickier cases. The second most common use of generics is for type tokens, Class, which embody type information both at compile-time and at runtime. For example, type tokens are used to [URL="http://java.sun.com/javase/6/docs/api/java/lang/reflect/AnnotatedElement.html"]retrieve annotations[/URL].
Be wary of other uses of generics in Java. Java's generics have significantly technical differences from templates in C++; Java generics are by design not a Turing-complete meta-language! Attempting to use Java generics to simulate features in another languages, like Haskell's pattern matching, is unlikely to lead to pleasant or idiomatic Java code. In a Java program, using pervasive type parameters to pass along other information throughout a program, [URL="http://www.daimi.au.dk/~madst/ecoop04/index.html"]such as to address code evolution issues[/URL], is also not a pleasant fit. A warning sign in API design is a Java class having more than two type parameters; this likely signals generics are being used in an awkward way.