Generics, for non collection types

J

jean

Hi,

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
 
A

Arne Vajhøj

jean said:
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 ?

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
 
S

Stefan Ram

jean said:
uses of generic types

I call them »parameterized types«.

Here is a class from my example implementation of monads in Java:

class Bind<ValueType,StateType,ProductType>
{
Operation<ValueType,StateType> firstOperation;
ParameterizedOperation<ProductType,StateType,ValueType> secondOperation;

Bind
( final Operation<ValueType,StateType> firstOperation,
final ParameterizedOperation<ProductType,StateType,ValueType> secondOperation )
{ this.firstOperation = firstOperation;
this.secondOperation = secondOperation; }

Operation<ProductType,StateType> composition()
{ return new Operation<ProductType,StateType>()
{ public ProductAndState<ProductType,StateType> execute( final StateType initialState )
{ ProductAndState<ValueType,StateType> intermediateProductAndState =
firstOperation.execute( initialState );
return secondOperation.of( intermediateProductAndState.getProduct() )
.execute( intermediateProductAndState.getState() ); }}; }}

http://www.purl.org/stefan_ram/pub/monaden

(German language Web page)

Like a comment, the type arguments enhance readability by
providing important information. /And/ the Java compiler will
even check at compile-time that this information is correct.

Of course - being out-of-context - the above class is still
difficult to understand, but still it might have coveyed the
idea.
 
L

Lew

jean said:
Hi,

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 ?

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/a...ml#sort(java.util.List, java.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.
 
L

Lew

Stefan said:
Of course - being out-of-context - the above class is still
difficult to understand, but still it might have conveyed the
idea.

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.
 
T

Tom Anderson

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.Class
java.lang.Comparable
java.lang.ref.Reference
factories of various kinds

tom
 
A

Arne Vajhøj

Lew said:
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.

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
 
A

Arne Vajhøj

Arne said:
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.

(and boxing/unboxing for simple types)

Arne
 
J

Joshua Cranmer

jean said:
What is the interest of generic types outside
the field of collection types ?

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).
 
T

Tom Anderson

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
 
A

Arved Sandstrom

Joshua Cranmer said:
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.
[ SNIP ]

To expand upon your above, there are lots of interesting uses of generics in
java.util.concurrent.

AHS
 
A

Arved Sandstrom

Stefan Ram said:
I call them »parameterized types«.

Here is a class from my example implementation of monads in Java:

class Bind<ValueType,StateType,ProductType>
{
Operation<ValueType,StateType> firstOperation;
ParameterizedOperation<ProductType,StateType,ValueType> secondOperation;

Bind
( final Operation<ValueType,StateType> firstOperation,
final ParameterizedOperation<ProductType,StateType,ValueType>
secondOperation )
{ this.firstOperation = firstOperation;
this.secondOperation = secondOperation; }

Operation<ProductType,StateType> composition()
{ return new Operation<ProductType,StateType>()
{ public ProductAndState<ProductType,StateType> execute( final
StateType initialState )
{ ProductAndState<ValueType,StateType> intermediateProductAndState =
firstOperation.execute( initialState );
return secondOperation.of(
intermediateProductAndState.getProduct() )
.execute( intermediateProductAndState.getState() ); }}; }}

http://www.purl.org/stefan_ram/pub/monaden

(German language Web page)
[ SNIP ]

And unfortunately I got a 403.

AHS
 
J

John B. Matthews

Joshua Cranmer said:
jean said:
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>
 
A

Andreas Leitgeb

Stefan Ram said:

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 &szlig; 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".
 
F

François Grondin

Hi

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top