views:

437

answers:

6

I liked the discussion at Differences in Generics, and was wondering whether there were any languages that used this feature particularly well.

I really dislike Java's List<? extends Foo> for a List of things that are Liskov-substitutable for Foo. Why can't List<Foo> cover that?

And honestly, Comparable<? super Bar>?

I also can't remember for the life of my why you should never return an Array of generics:

public T[] getAll<T>() { ... }

I never liked templates in C++, but that was mostly because none of the compilers could ever spit out a remotely meaningful error message for them. One time I actually did a make realclean && make 17 times to get something to compile; I never did figure out why the 17th time was the charm.

So, who actually likes using generics in their pet language?

+12  A: 

Haskell implements type-constructor parameterisation (generics, or parametric polymorphism) quite well. So does Scala (although it needs a bit of hand-holding sometimes).

Both of these languages have higher-kinded types (a.k.a. abstract type constructors, or type-constructor polymorphism, or higher-order polymorphism).

See here: Generics of a Higher Kind

Apocalisp
+5  A: 

Heck, English doesn't even implement generics well. :)

My bias is for C#. Mainly because that is what I am currently using and I have used them to good effect.

Craig
+1  A: 

I use .Net (VB.Net), and haven't had any problems using generics. It's mostly painless.

Dim Cars as List(Of Car)
Dim Car as Car

For Each Car in Cars
...
Next

Never had any problems using the generic collections, although I haven't gone so far as to design any objects that use generics on my own.

Kibbee
+7  A: 

I think the generics in Java are actually pretty good. The reason why List<Foo> is different than List<? extends Foo> is that when Foo is a subtype of Bar, List<Foo> is not a subtype of List<Bar>. If you could treat a List<Foo> object as a List<Bar>, then you could add Bar objects to it, which could break things. Any reasonable type system will require this. Java lets you get away with treating Foo[] as a subtype of Bar[], but this forces runtime checks, reducing performance. When you return such an array, this makes it difficult for the compiler to know whether to do a runtime check.

I have never needed to use the lower bounds (List<? super Foo>), but I would imagine they might be useful for returning generic values. See covariance and contravariance.

On the whole though, I definitely agree with the complaints about overly verbose syntax and confusing error messages. Languages with type inference like OCaml and Haskell will probably make this easier on you, although their error messages can be confusing as well.

Jay Conrod
I mostly agree with you, but I have two things to point: type erasure can be a pain sometimes, and you can't use primitive types with generics.
Martinho Fernandes
+3  A: 

I'll add OCaml to the list, which has really generic generics. I agree that Haskell's type classes are really well done, but it's a bit different in that Haskell has no OO semantics, but OCaml does support OO.

toby
A: 

I think that C# and VB.NET do a good job with generics.

Kevin Kershaw