What is the interest of generic types outside
the field of collection types ?
All the examples I found are based
on collection types (thanks to generics
, we avoid an explicit cast when we get an element
from a collection ... ok, that's fine.
But are there any other interesting uses of
generic types ?
thanks !
jean
I would say that Java generics is 80-80% about
generics'fying collections/containers.
In a few cases it can be used for algorithms as well.
That requires restrictions on the types.
But there are two problems:
- the implementation of generics in Java somewhat limits
what it can be used for
- when using generics for anything beyond simple collections
the code may become shorter, but usually becomes much more
difficult to read and understand
Arne
Indeed there are. To pick one:
<http://java.sun.com/javase/6/docs/api/java/util/Comparator.html>
Wildcards make generics way more interesting. When Collections get together
with Comparator, they use wildcards to lock the type system down.
<http://java.sun.com/javase/6/docs/api/java/util/Collections.html#sort(java.util.List,%20java.util.Comparator)>
Note that the Comparator is a 'Comparator<? super T>'.
The point of generics, particularly the bizarrely non-reifiable Java version
of them, is "typehood". I coin this term to encompass thinking of design and
implementation type-wise - once you get to that frame of mind you
automagically create all kinds of code that won't throw cast-related
exceptions. The Comparable interface is an example of the power of "typehood"
applied to the power of "programming to interfaces". Interfaces' raison
d'être is typehood, too. This thought / design process places type analysis
über alles. Generics, especially wildcard generics, and interfaces cooperate
to express programs in the language and ontology of typehood.
As an aside - one possible advantage of type erasure is that there is no
performance penalty from generics, potentially quite the contrary due to the
elimination of casting exceptions.
The broad answer to your question is that generics and interfaces are great
for expressing type-based programming.
--
Lew
Indeed it did - and the complexity of the snippet is exactly the complexity of
the algorithm itself. For this one cannot blame any computer language.
The value of compile-time checking actually increases with the complexity of
the type-logic statements one wishes to enforce.
People complain sometimes that Java generics are complicated. Perhaps this
complexity is inherent to reasoning about type safety and type invariants. I
think it is.
With generics, you get some help from the compiler. Incorrectly formulated
type statements will result often in compiler errors. Blaming generics for
this is shooting the messenger. One will find that the error is real, that it
represents a misstatement in the type logic of one's design.
Another outcome is over-permissiveness. The type statements don't
sufficiently constrain the operation, allowing too many illegal combinations
of types and insufficiently preventing cast issues. Good unit tests help
flush this out.
This results in a better type factoring of one's interfaces, and correct
representation of their interrelationships. One that thereafter is enforced
at compile time.
The value of compile-time enforcement and simultaneous formal documentation of
a difficult type analysis cannot be overstated.
--
Lew
java.lang.Class
java.lang.Comparable
java.lang.ref.Reference
factories of various kinds
tom
--
A hypothesis or theory is clear, decisive, and positive, but it is
believed by no one but the man who created it. Experimental findings,
on the other hand, are messy, inexact things, which are believed by
everyone except the man who did that work. -- Harlow Shapley
Unfortunately, Java's "generics" are implemented in such a way that
they don't support many generic programming techniques. The basic
problem is type erasure -- Java doesn't preserve the type used to
parameterize a generic class. This means that techniques like Coplien's
Curiously Recurring Template Idiom (a.k.a. the Curiously Recurring
Template Pattern or CRTP), which allows generic behavior to be added to
any class, i.e.:
template <class T> class Singleton
{
private:
static T instance_;
public:
static T& instance() { return instance_; }
};
class Foo : public Singleton<Foo>
{
. . .
};
work with C++ templates but cannot be implemented using Java's generics.
I like generic programming particularly for mix-in classes to
essentially generate code safely. It's too bad Java doesn't allow that.
Regards,
Patrick
PS: Singleton is just an example, I don't want to get into that
religious war. I prefer Monostates myself.
------------------------------------------------------------------------
S P Engineering, Inc. | Large scale, mission-critical, distributed OO
| systems design and implementation.
http://www.spe.com/pjm | (C++, Java, Common Lisp, Jini, middleware, SOA)
Generics with type erasure may be a tiny little bit faster due to
elimination of casting exceptions.
But generics without type erasure can be a lot faster due to
elimination of casts.
Arne
(and boxing/unboxing for simple types)
Arne
Probably 90% or more of uses of generics will come from some utility
package, like java.util, or com.example.util. Within java.util, there is
a non-collection-related class (ServiceProvider) that uses generics;
there are also classes elsewhere that use them. java.lang.Class is one;
the java.lang.ref package also uses them heavily.
Common examples of where people roll their own generics is a Pair (or
some other tuple-like) class (Pair<A, B>); Matrix is a second class that
tends to be generified. A general assumption people make is that
operator overloading--if accepted into Java--would be founded upon
generics. I, in fact, have an example of using generics for operator
overloading in a recent message to this newsgroup.
Note that generics are essentially abstracting over their contents; it
can be anything (within some type bounds). The most widely-used cases
will be fundamental data structures. Other use cases would be limited to
instances which would (in C) be represented by a void* pointer (the tree
visitors internally used by some Java tools commonly use generics in
this fashion).
--
Beware of bugs in the above code; I have only proved it correct, not
tried it. -- Donald E. Knuth
> jean <je...@pasdadresse.com> writes:
>> What is the interest of generic types outside the field of collection
>> types ?
>>
>> All the examples I found are based on collection types (thanks to
>> generics, we avoid an explicit cast when we get an element from a
>> collection ... ok, that's fine.
>>
>> But are there any other interesting uses of generic types ?
>
> Unfortunately, Java's "generics" are implemented in such a way that
> they don't support many generic programming techniques. The basic
> problem is type erasure -- Java doesn't preserve the type used to
> parameterize a generic class. This means that techniques like Coplien's
> Curiously Recurring Template Idiom (a.k.a. the Curiously Recurring
> Template Pattern or CRTP), which allows generic behavior to be added to
> any class, i.e.:
>
> template <class T> class Singleton
> {
> private:
> static T instance_;
>
> public:
> static T& instance() { return instance_; }
> };
>
> class Foo : public Singleton<Foo>
> {
> . . .
> };
>
> work with C++ templates but cannot be implemented using Java's generics.
Isn't the limitation actually that you can't inherit static methods in any
useful way?
tom
--
The best way I know of to win an argument is to start by being in the
right. -- Lord Hailsham
> On Sat, 22 Nov 2008, jean wrote:
>
>> What is the interest of generic types outside
>> the field of collection types ?
>>
>> All the examples I found are based
>> on collection types (thanks to generics
>> , we avoid an explicit cast when we get an element
>> from a collection ... ok, that's fine.
>>
>> But are there any other interesting uses of
>> generic types ?
>
> java.lang.Comparable
^^^^
util, of course.
To expand upon your above, there are lots of interesting uses of generics in
java.util.concurrent.
AHS
And unfortunately I got a 403.
AHS
In the case of this idiom, the problem is the inability to create
an instance of T, static or otherwise.
Regards,
Patrick
> jean wrote:
> > What is the interest of generic types outside
> > the field of collection types ?
[...]
> Common examples of where people roll their own generics is a Pair (or
> some other tuple-like) class (Pair<A, B>); Matrix is a second class that
> tends to be generified. A general assumption people make is that
> operator overloading--if accepted into Java--would be founded upon
> generics. I, in fact, have an example of using generics for operator
> overloading in a recent message to this newsgroup.
[...]
That reminds me: the JScience library uses generic interfaces to
characterize the operators available to other generic types:
<http://jscience.org/api/org/jscience/mathematics/structure/package-summa
ry.html>
<http://groups.google.com/group/comp.lang.java.programmer/browse_frm/thre
ad/c05f38c9e4c61b10?hl=en>
--
John B. Matthews
trashgod at gmail dot com
http://home.roadrunner.com/~jbmatthews/
'lang' was correct.
<http://java.sun.com/javase/6/docs/api/java/lang/Comparable.html>
It's 'java.util.Comparator'
<http://java.sun.com/javase/6/docs/api/java/util/Comparator.html>
I do that one a lot also.
--
Lew
Aaaaaargh!
This is what control-shift-O does to you!
tom
--
Only the bagel has the correct aspect ratio.
Much obliged. Also a good chance to practise my German. :-)
AHS
Now, that it works, it contains a few minor mistakes.
Some typoes: "Eine Monoid"->"Ein Monoid"/"Eine Monade",
"festgelegen"->"festlegen", "solche eine"->"solch eine"
(without any claim of completeness)
Also many of the ß characters are no longer
correct (daß -> dass, etc.). Probably the texts
predate the latest German spelling-reform.
I wouldn't have cared to point those language
mistakes out, if someone else didn't indicate
he would refresh his German with this text. :-)
Apart from that, at one place (namely where the neutral
element is introduced) I noticed that you changed to use
a colon instead of the semicolon.
Also, I doubt that a parameterless operation is necessarily
a constant, as seems to be implied by: "... und 'g' eine nicht-
parametrisierte Operation bezeichnet (also eine bestimmte Operation),
die einer Konstanten (im Gegensatz zu einer Funktion) entspricht."
Since such an operation may still depend on the pre-state and
leave a different post-state, constant may not be an adequate
term. Most languages do distinguish parameterless functions from
constants (leaving out pure-functional ones) at least by naming
them "pseudo-variables".
Another example I'm working on is a class of algorithm that apply to
specific objects :
public abstract class Algorithm<T extends MyObject>
{
public Algorithm()
{
// NOP
}
public abstract void apply(T anObject);
}
This way, I'm sure to limit the scope of the algorithm to a very specific
type of object, instead of apply it to something more general like MyObject.
And this is not a collection.
Hope this helps.
François
"jean" <je...@pasdadresse.com> a écrit dans le message de news:
49288c73$0$6839$426a...@news.free.fr...
Certainly not.
In my experience there are at least two common cases of parameter-less
methods whose return values vary over time.
Getters, when there's a setter for whatever they get, or it otherwise is
changeable.
And "next" methods, like InputStream.read(), Random.nextInt(),
Iterator.next(), and the like, and anything else they affect, like
Iterator.hasNext() and FileChannel.position().
Now, a parameter-less method on an //immutable// object might be much
more likely to have a constant return value.
- jenny
Join the dark side. Switch to netbeans!
- jenny
Ah, but here we're talking about monads. Monads are something a bit
special, and come from the crazy mixed-up world of functional programming.
There, things like setters and next() do not exist. I haven't read
Stefan's java, or his german, so i can't be sure that this applies to the
operations we're talking about translation into java, but a no-arg
function in a functional language *is* a constant. Although possibly *not*
when monads are involved, since that's kind of the point of monads.
So basically i have no idea.
But i do know that some people, when confronted with a problem, think "I
know, I'll use monads." Now they have S(1) problems.
tom
--
Tomorrow has made a phone call to today.
J. Davidson wrote:
> Join the dark side. Switch to netbeans!
Alt-Shift-I, then.
--
Lew
JSR777 - Standard for key mappings in Java IDE's
Arne
I happen to think the way generics are used in the Emum<E extends
Enum<E>> is quite interesting. I've used that idiom myself in several
data structures where I want to swap out some internal class.
For instance, a generic Tree data structure should have the notion of
Nodes, but we want the freedom to implement those Node classes in
different, efficient ways depending on the Tree type. Heaps are tree,
but can be efficiently implement on top of an array. A Red-Black Tree
needs Nodes with an extra "red" boolean flag, etc....
One can implement a generic data type like this:
public interface Tree<V, N extends Node<V, N>> {}
public interface Node<T, Q extends Node<T, Q>> {}
public interface BinaryTree<K extends Comparable<K>, V, N extends
BinaryTreeNode<K,V,N>> extends Tree<E, N>
public interface BinaryTreeNode<S extends Comparable<S>, T, Q extends
BinaryTreeNode<S, T, Q>> extends Node<T, Q>
Now, a concrete implementation of a Red-Black Tree class might look
like this
class RBTree extends BinaryTree<Integer, String, RBNode> {}
class RBNode extends BinaryTreeNode<Integer, String, RBNode> {}
All the complicated-looking generic declarations just make sure that
when I glue a TreeNode class onto a Tree class the Key and Value types
all match up. This lets me have a very loose coupling of the Tree and
Node classes, but still enforce type-safety.
-Lucas
The construct Foo<T extends Foo<T>> allows the class to use T as a
kind of self-referential type, e.g. Tree and
(Sudden realization) Oh, that's where the infinite generic types comes in.
> For instance, a generic Tree data structure should have the notion of
> Nodes, but we want the freedom to implement those Node classes in
> different, efficient ways depending on the Tree type. Heaps are tree,
> but can be efficiently implement on top of an array. A Red-Black Tree
> needs Nodes with an extra "red" boolean flag, etc....
I'm not sure how useful a setup would be, since most tree-based
structures don't all need the same access points. A heap implementation
isn't going to care much about postorder tree traversal after all.
Besides, this usage would qualify as "collection types," if you want to
be pedantic.
Is that a real JSR? How in the bloody blazes can Java define the keystrokes
for applications? That's not part of the language.
What a stupid idea.
--
Lew
Yes, but it's nice to have the consistency to write code like this
BinaryTree<E> tree = new BinaryHeap<E>();
and then go about one's business. And besides, someone might want to
extend the BinaryHeap class in such a way that the postorder traversal
is now meaningful...
> Besides, this usage would qualify as "collection types," if you want to
> be pedantic.
Sure, but the real point of my example was to show how generics can be
used to combine the implementation classes of two coupled interfaces
in a type-safe manner.
-Lucas
Yeah. I've been arguing on the mailing list for weeks to have
alt-shift-leftarrow-downarrow-rightarrow-P be the standard key combo for
HADOKEN!!!, but the idiot committee just aren't listening.
tom
--
The literature is filled with bizarre occurrances for which we have
no explanation
Lew wrote:
>> Is that a real JSR?
Arne Vajhøj wrote:
> No - it was a joke.
>
> (it is not on http://jcp.org/en/jsr/all !)
Ha. Funny, and you got me!
And educated me. Thanks for the link.
--
Lew
I also use it in a generic Factory<T> interface that I've created, as
well as in many "generic" classes that need to know only the parent type
of a particular object reference, but may be extended for more specific
types.
--
Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>