Fog Creek Software
Discussion Board




Anders Hejlsberg On C# vs Java Generics

There's an interesting comparison of the proposed C# and Java generics implementations at Artima.com - http://www.artima.com/intv/generics.html

--The Java implementation sounds broken. Should Sun have removed the "has to run on an existing JVM" constraint?

John Topley (www.johntopley.com)
Wednesday, January 28, 2004

They should. After all, C# and Java _technically_ don't need generics -- they have a single-rooted object tree, and that would  suffice to deal with arbitrary types.

So why do we still want generics? Type safety is one thing, but another is performance. Repeatedly boxing and unboxing value types slows a .NET program down to a crawl.

C# generics solve this problem by creating a specialized template instance for each value type, so you get the same execution speed as for hand-written strongly-typed code.

Java generics don't seem to address this issue at all, on the other hand. IMO this will further increase the distance between the two languages, rather than allow Java to catch up.

Chris Nahr
Wednesday, January 28, 2004

> Should Sun have removed the "has to run on an existing JVM" constraint?

Java has a huge installed base now, so removing this requirement would be foolish.

I personally find generics far overrated; it's easy enough to have an object encapsulate the List (or other collection) and enforce the correct typing:

private List customers;

public void addCustomer(Customer c) { customers.add(c); }

// Guaranteed to have only customers
public List getCustomers()
{
    returnCollections.unmodifiableList(customers);
}

(The point about reflection is still true, however; in the past, I've actually added a type method for reflection to work properly).

I've read most of the Artima series with Anders. He's a brilliant guy, but let's face it: the articles are at least 50% cheerleading. You know, when you start a sentence with "We're better because....."

Portabella
Wednesday, January 28, 2004

I would be interested in knowing if the difference in implementation results in a difference in performance.

The point he makes about reflection seems valid.  It would be nice to know what it is a list of via reflection.  I can't help but think that in most cases this would not be an issue.  I mean, when you pull something out of the List you can find out its type.  For the most part it seems to me that if the type of the List mattered you would handle this with a Factory pattern or just a few different method signatures for whatever method you would be sending the list to. 

I would need to see some examples of where this ability would lead to better design.

name withheld out of cowardice
Wednesday, January 28, 2004

Generics go way beyond Lists and Collections; they allow you to write your own abstract data structures for use by others while ensuring consistency of the elements in the data structure.

Java's problems with generics are only implementation issues that can be transparently fixed by future versions of the JVM or Java compiler.

NoName
Wednesday, January 28, 2004

> Generics go way beyond Lists and Collections

I don't think so. What they do is reduce the amount of boilerplate code that you have to write, which is nice, but not by any means essential.

If you disagree -- give an example of something that you could do with generics that would be difficult or impossible without them.

Portabella
Wednesday, January 28, 2004

Generics provide compile-time type checking of the elements in whatever data structure you are using, so you avoid unpredictable ClassCastExceptions that may occur when every element is an Object.  Without generics, such an exception would occur only when extracting an element, not when placing it in the structure, so the occurrence of the exception could be quite distant from the cause, leading to lots of wasted debugging time.

If you have a small group of very good programmers who can be trusted to do things right, it's not such a big deal. But when you have a large group of average programmers, as is often the reality in any big organization, having the compiler enforce this consistency is a great benefit.

NoName
Wednesday, January 28, 2004

> If you have a small group of very good programmers who can be trusted to do things right, it's not such a big deal. But when you have a large group of average programmers, as is often the reality in any big organization, having the compiler enforce this consistency is a great benefit.

NoName, I agree with you, but my deeper evaluation is that if you don't have a group of programmers that you trust to do the right thing, you are basically fucked. Generics have nothing to do with this; you are basically describing the Big Ball of Mud.

Portabella
Wednesday, January 28, 2004

> If you disagree -- give an example of something that you could do with generics that would be difficult or impossible without them.

As he said, you can do it all in C ... or assembler. But now you needn't.

Christopher Wells
Wednesday, January 28, 2004

Compile time checking is very nice but I disagree that without generics you could only know there is a problem when extracting from the list at runtime.  You could cast any object to the appropriate class before insertion and catch any ClassCastExceptions.

In fact wouldn't the compiler make you do this in any code that had the possibility of inserting an innapropriate class?

name withheld out of cowardice
Wednesday, January 28, 2004

> As he said, you can do it all in C ... or assembler.

Uh, that's like saying that the code could all be ported to Commodore 64s. It may be true in some abstract, theoretical sense, but it's totally irrelevant in this context.

> I disagree that without generics you could only know there is a problem when extracting from the list at runtime.

Me too (see my earlier post).

> In fact wouldn't the compiler make you do this in any code that had the possibility of inserting an innapropriate class?

No, it doesn't.

Portabella
Wednesday, January 28, 2004

A not-so-careful programmer working on the other side of the building (or the other side of the world) might add a type that you don't expect into the data structure.  Or when a system becomes old and you have to enhance it, without generics YOU might not know what types something expects, until you spend a lot of time tracing through the code.

Does having large numbers of mediocre programmers mean we're f*#$@?  Not always -- most big systems in large corporations were built that way, and they continue to run and keep the business afloat (albeit with much expense and waste).  Features like generics are good for limiting the destructive powers of mediocre programmers, to avoid you from becoming f@$#*.

Remember, if you are in control and you have a staff of good programmers, you don't have to use generics.

NoName
Wednesday, January 28, 2004

Portabella-

I haven't used this facility yet (not sure it's even out) but take this example:

public void addObject(Object object){
  this.masterList.add(object);
}

if this.masterList is a List defined to accept only Strings won't the compiler throw an error unless you cast object to a String first?

name withheld out of cowardice
Wednesday, January 28, 2004

> if this.masterList is a List defined to accept only Strings won't the compiler throw an error unless you cast object to a String first?

I believe so.

I thought you were talking about the existing compilers, not the upcoming generic-aware compilers. My apologies.

Portabella
Wednesday, January 28, 2004

Well, just don't let it happen again :)

name withheld out of cowardice
Wednesday, January 28, 2004

Yes, you can write your own ListOfCustomers, but why?  Maybe if the bulk of your programming is mechanical activity, and you've grown tolerant of such, you might not resent doing stuff the compiler can do for you.  I *do* resent having my time wasted.  Sure, you can get by without parameterized types, but that's silly.

Even if you have no aversion to doing monkey-work, here's another rationale (among many) for parameterized types: interoperabililty.  Let's say Portabella writes a ListOfStrings, like his ListOfCustomers, as part of his new extensible accounting application.  Now I write my new extensible purchasing application with my own ListOfStrings.  Then *you* write some glue between them.  You have to do more monkey-work -- like translating a veal.ListOfStrings into a portabella.ListOfStrings -- that would be unnecessary if both applications used a generic List<String> class.

Muse a little about how much nicer the various Java libraries would be with that kind of uniformity available.

Or... we could all just buy lots of paper tape, and do everything with Turing machines.

veal
Wednesday, January 28, 2004

In C#/VB.Net, you can create a strongly-typed collection by inheriting from the CollectionBase abstract class.  It simplifies the process of developing a type-safe collection, but there's still some drudgery involved.  Also, CollectionBase just stores everything interally as an Object, so there will be a big performance penalty from boxing if you're using it to store value types.

In practice, it seems that most developer take the easy road and just use weakly-typed ArrayLists.  Generics will hopefully give people an incentive to develop better habits.

Robert Jacobson
Wednesday, January 28, 2004

> Yes, you can write your own ListOfCustomers, but why?

I'm not disagreeing, merely pointing out that such monkey-work is actually a very small fraction of the code in almost all cases that I've seen.

Sure, I'll use generics when they come along, and are well-tested enough (IMO, that's the main reason to keep writing your own for now), but I'm not expecting huge improvements: it's very much an incremental, now-I-don't-have-to-do-it-by-hand thing. That's why I say they're overrated.

Portabella
Wednesday, January 28, 2004

> that would be unnecessary if both applications used a generic List<String> class

You could do this easily now by using a String array (as Anders says in the interview). You want both a Collection and an array? Expose both, or provide utility methods to convert between them.

Again, I'm sure that it'll be cleaner and easier with generics, but there is no fundamental difference in what you can and can't do.

Portabella
Wednesday, January 28, 2004

Portabella must get paid by the hour.

--
Wednesday, January 28, 2004

There is no fundamental differences between what you can and can't do, but they are still a big deal.

I forget where I read it, but it was found that higher level languages do not, in fact, reduce the average amount of bugs per line of code.  What they *do* do is reduce the lines of code, thereby reducing bugs (in exchange for some tradeoffs, of course).

Generics offer the same advantage.  They don't do anything you couldn't do with strongly typed lists.  However, every time you implement your own strongly-typed list, you run the risk of doing something wrong.  Implementing a strongly-typed list takes a non-negligible amount of time (even if you use a macro, like I do).  Generics greatly eliminate the temptation to just use an arraylist.

Richard P
Wednesday, January 28, 2004

> What they *do* do is reduce the lines of code

All languages are equal, but some languages are more equal than others.

If we really cared about small code size, we'd use Python or Ruby, not C# and Java.

The fact that we *don't* usually see these languages in enterprise environments means that small code size is not the driving factor, or at least far from the most important.

Portabella
Wednesday, January 28, 2004

> If we really cared about small code size, we'd use Python or Ruby, not C# and Java.

> The fact that we *don't* usually see these languages in enterprise environments means that small code size is not the driving factor, or at least far from the most important.

Perhaps it's lack of marketing $$. Though they do seem to be gaining in the last year or two for lots of tasks, especially on *nix machines. The GUI builders are not up to snuff compared to some of the commercial tools either. But a lot of really great programmers are saying they are MUCH more productive in getting to fully debugged apps. But there is also the critical mass issue, as a company needs to know they can find programmers with those skills in the future.

Guy T
Wednesday, January 28, 2004

"If we really cared about small code size, we'd use Python or Ruby, not C# and Java.

The fact that we *don't* usually see these languages in enterprise environments means that small code size is not the driving factor, or at least far from the most important"


You're right, productivity typically is the driving factor. Therefore, if something like generics bring increased productivity and reduce the risk of bugs then where's the problem?

You seem to be suggesting that generics are only good if you write less than perfect code. No matter how good you are, you will make mistakes. You don't even have to be asleep at the switch to introduce a bug in a team environment.

Bottom line for me is that I won't have to choose between an Array, ArrayList or rolling my own collection class anymore. If the performance is there, then I'll be quite happy to see them.

Mark Hoffman
Wednesday, January 28, 2004

> if something like generics bring increased productivity and reduce the risk of bugs then where's the problem?

No problem at all.

My point is that it's like an optimization where the code is only spending 10% of its time. Should we do it, if it's free (*)? Sure. Is it going to help a lot? No.

* If it requires an upgrade to the runtime, then it's not really free either but leave that aside.

Portabella
Thursday, January 29, 2004

Perhaps future versions of the JVM will handle generics better, but at the transition java will support the existing JVMs. Sounds cool. MS has the tradition of deprecating stuff in favor of the newest technologies. MS keeps the support, but creates new stuff that no longer use that old stuff. VB anyone ? ASP ? :P

Dewd
Thursday, January 29, 2004

I'm not sure why it's so important to support existing JVMs in the first place. Isn't the JVM updated every couple of months anyway? And don't some program already require a certain minimum version? Where's the problem, exactly?

Chris Nahr
Friday, January 30, 2004

> Where's the problem, exactly?

The class files. Java has kept the same class file format for many releases now, and they are (understandably) reluctant to change it, because LOTS of tools, utilities and libraries depend on it.

Portabella
Friday, January 30, 2004

Hmm... but couldn't they work around that by instantiating templates during compilation, and storing only the strongly-typed versions in the class files?

If you wanted to use someone else's templates you'd need the source code but that doesn't sound like a huge disadvantage.

Chris Nahr
Friday, January 30, 2004

I used to hate C++ templates, but I've come to realize their power as I matured as a programmer.

You, ideally, want both a vector < int > and a vector < object > to give yourself expressive flexiblity.  Sure, if all you have is the second, you can just assume that it's all ints, but remember that you are still paying a price -- the VM is checking for type safety, even if you aren't.  Anders covers this well.

The one thing is, I don't think a good programmer trusts even themselves.  Do I trust myself to properly use an array of void pointers throughout a chunk of code?  Hell no.

Flamebait Sr.
Friday, January 30, 2004

Generics provide two improvments.

1. They are both a compile time, and runtime atempt
by the CLR/Compiler to enforce the user to do the "Correct
thing".

2. They are a BIG preformance enhancement.

As stated in by other posters, professional programmers  already try and do the right thing, so generics may not seem to be that much of a benifit on the surface, but languages are always evolving to make things easier, safer, and faster.

As for the performance, no "Good Practice" approach can give you the performance beinfits that generics give you.

Motoman
Tuesday, March 02, 2004

*  Recent Topics

*  Fog Creek Home