Tapestry Training -- From The Source

Let me help you get your team up to speed in Tapestry ... fast. Visit howardlewisship.com for details on training, mentoring and support!

Thursday, July 07, 2005

<> vs. () makes me :-(

All I wanted was fewer casts. I'm sick of typing all those casts (they tend to get out of control when using EasyMock). The compiler knows enough about the left and right side of my assignments to require a cast, why can't it just provide it (this is the Dave Thomas observation).

Now, in an attempt to simplify things, we've replaced casts with generic type constraints. So instead of:

Map _map = new HashMap();

public RegistrationData getRegistration(String userId)
{
  return (RegistrationData) _map.get(userId);
}
With generics we get:
Map<String, RegistrationData> _map = new HashMap<String, RegistrationData>();

public RegistrationData getRegistration(String userId)
{
  return _map.get(userId);
}
So, much more repetition and uglier code to avoid that one little cast. A cast the compiler could just as easily have provided for me? One that still exists at runtime (that's type erasure). This is simpler?

5 comments:

afsina said...

1- you dont have to use generics if you do not like the way it looks.
2- the case you show is just a one liner, an extreme case. usually generics makes the code simpler. i think safety is much important anyway.

Unknown said...

Yes and no. What burns me is that when I start to pass an genericized object around, those type qualifiers, inside the < and >, keep coming back. I believe you can create an interface to consolidate that.

The mantra of compile-time safety is ebbing. This is why Ruby is starting to kick Java's ass. I've been talking about the difference between "Pragmatic" languages (Ruby) and "Dogmatic" languages (Java).

I chose "Dogmatic" carefully; Java has an architect, Gilad Bracha, whose title is "Chief Computational Theologist".

Because of type erasure and the like, you still can't be sure that the code above doesn't throw a ClassCastException (an assignment to _map using a cast would do it, because the type qualifiers are "erased").

More importantly, compile-time safety is a bit of a fraud given that you're going to write tests. And the tests will not throw ClassCastExceptions. So if the compiler simply injected the casts for us, invisibly, we'd be at the same point ... with much more readable code.

Smalltalk IDEs still blow away Java IDEs in terms of refactoring DESPITE the lack of compile time type information. Again, Pragmatism vs. Dogmatism.

Generics are a big experiment of questionable value that has been unleashed on us all, ready or not. It can't be removed (Sun never removes anything from Java), so we're stuck with it, like it or not, forever.

I used to scoff at the notion that "Java is the new COBOL". Not anymore.

alang said...

In my (not very wide) experience, I end up typing class names slightly fewer times with generics than with casts. This is because code tends use variables more often than it declares them. YMMV.

On the whole, I think generics are a good thing for Java, even if they are not as amazingly good as the original evangelistic literature promised.

Trying to be pragmatic, my response is to embrace generics when programming in Java on one hand, while using my other hand to find projects that don't require Java at all. And it sounds like you're ahead of me on that score.

Unknown said...

Instead of generics they should've implement type inference in java.
This way you still would get most of the pros of generics including comile time checking and greatly simplify coding.

Type inference is implemented in such static typed languages as Haskell and Clean.

Charles Miller said...

Is it just me, or does the subject line of this post end up looking like a big ASCII fish?