| «« jid3rL with FramesGroup | jid3rL is Building Nightly »» |
|
About
I'm Ryan Lowe, a Software Engineering graduate living in Ottawa, Canada. I like agile software development and Ruby on Rails.
I write this blog in Canadian English and don't use a spell checker. Typos happen.
Projects
» Full-time Ruby on Rails freelancer
» Full-time with Rails since May 2005 » Former committer for RadRails (now Aptana) » I also have a few Rails side-projects in development: 1. wheretogoinTO.com Toronto nightlife 2. Hey Heads Up! TODO list and sharing 3. Layered Genealogy family history research 4. foos for foosball scoring 5. fanconcert for music fans (on hold) Hiring Rails developers? I can telecommute by the hour from Ottawa, Canada »» Email: rails AT ryanlowe DOT ca
BulletBlog
Now hosted on Hey! Heads Up -- check it out!
Syndication
Pings
Recent
Derek Lowe's (Ryan's older brother) words at Ryan's funeral
blog@ryanlowe.ca no more Forging Email Headers: Good, Bad or Ugly? Sarcastic Dictionary (Part 1 of Many) Tags Hierarchies Twisting Rails is Risky Business Risky Business? My Take on Early Alphas Whoa, it's August 2007 Closing Comments A Postscript to "Growth at the grassroots" »» All Blog Posts
Linkage
del.icio.us/ryanlowe
technorati/ryanlowe.ca/blog Aurora Roy Jim Andrew Trasker Travis Kibbee Karen Dr. Unk Ayana Van Bloggers Joel Spolsky Robert Scoble Tim Bray Dave Winer Raymond Chen James Robertson Ruby/Rails Bloggers rubyonrails.org weblog David Heinemeier Hansson Dave Thomas James Duncan Davidson Mike Clark Jamis Buck Signal vs. Noise Tobias Luetke Amy Hoy: (24)slash7 Jeremy Voorhis Eclipse Bloggers Planet Eclipse EclipseZone Luis de la Rosa Eclipse Foundation Kim Horne Billy Biggs Ian Skerrett Mike Milinkovich Bjorn Freeman-Benson Denis Roy
Archives
|
ClassCastExceptions are Useless?
James Robertson spotted something in comp.lang.smalltalk: Just curious, but how many people out there using static languages actually try to pass invalid types to methods? How many Java users commonly get ClassCastExceptions at runtime? When using Java Collections I get ClassCastExceptions at runtime periodically, but it's usually because I'm wrapping the collection inside another class that has methods returning a specific type instead of just Object. When I retrieve the object from the collection I cast it to that type. What's the real reason I get ClassCastExceptions? Because I refactor a lot. After a refactoring the wrapper class to use B instead of A you might be putting a type B into the collection and incorrectly casting it to the old A in a wrapper class method[1]. This problem will go away when generics are introduced and I can specify the type I want a collection to contain. The compiler will tell me I'm trying to put a B into collection<A> and I'll be forced to refactor it to collection<B>. Then the compiler will tell me I'm casting an item from collection<B> to an A (the place where the ClassCastException formerly occured for me). Actually Eclipse will tell me these things as I type, instead of at compile time[2]. As I understand it, and I could be way wrong as usual, languages like Smalltalk don't have this problem because they don't enforce type, so you never cast an object coming out of a collection (I assume there is a complementary group of classes to Java Collections in Smalltalk). If I were refactoring the same problem in Smalltalk, without the ClassCastException I may never know that I'm returning an object of the wrong type after the refactor (A instead of B). To catch this problem, you'll need good unit tests and you'll need to change them all from using A to B. You could always just nuke the A class, and the compiler will tell you it's invalid. With static typing in Java and generics, you don't have to nuke A. [1] Note: this is different from putting in new type A' and incorrectly casting it to the old version of A. A refactoring IDE like Eclipse would change all of the references of A to A' and you wouldn't get ClassCastExceptions because A doesn't exist any more. [2] Eclipse is compiling the code in the background as I type so I don't need to compile it after. Update 11:41 am James responds: You don't have this problem in Smalltalk because it's not the sort of problem you tend to get yourself into, period. Say I had a collection holding Foos. If I refactor, and I end up having a collection holding Bars (completely incompatible), then I have bigger problems. Even so, I would have had to refactor all the surrounding code that accesses the collection elements - and if I didn't have tests under those circumstances, I'm in trouble whether I have static typing or dynamic typing. To be brutal, if you trust the compiler to solve this for you, then you shouldn't be writing code. I agree, testing is critical. If you're making up a new class you have to unit test it, and tests will catch refactoring errors from B to A in Java or Smalltalk. I wouldn't trust the compiler to test the result of a refactoring for me any farther than I could throw it, but with static types and generics it will be a lot more obvious when I break something. This probably seems like type hand-holding, but it's nice to see something break immediately as you type it, just like you expect it to -- even before you run the unit test suite. It's good immediate feedback. If you were unable to unit test (as stupid as that sounds, most people still don't) would you rather use a dynamically or statically typed language? Would static typing help? Assume for this question you are equally familiar with Java and Smalltalk and neither has an advantage in that respect. Personally I'm still in Java land because it's what I need to know -- at the very least -- to get a job. Java is in more places than Smalltalk or Python. I'll move on to Python or Smalltalk in a bit, and if I've used Java and know it well I'll be better informed about the differences between the languages. I still have faith that I will "see the light" in regards to dynamically typed languages. I was just stating a case for ClassCastException in Java. Update 1:34 pm Ian Bicking says on his blog: A tool can analyze statically typed code and say with some confidence exactly where a class or method is used -- in Smalltalk, Python, or other dynamically typed languages, refactoring is just a string match. Good naming practices can make that string search more reliable, but it's still just strings, not a fully type-annotated source. Interesting! Posted at August 10, 2004 at 09:01 AM ESTLast updated August 10, 2004 at 09:01 AM EST Comments
Like Eclipse, Smalltalk environments have refactoring tools (they had them first, in fact). I don't have automated refactoring tools in C++, so I have to rely on the compiler to find problems involving renaming a class, variable or method, or retyping a method result or method argument (or templated container). Usually this works, but C++'s sometimes automatic type conversions like int = bool = pointer don't give me error messages for a type-change. Please don't use the word "refactoring" for any changes that change the behavior of the software. "Refactoring" means "improving the design without changing the behavior". If a collection of A's has different behavior than a collection of B's or a collection of A's and B's, then you're rewriting, not refactoring. » Posted by: keith ray at August 10, 2004 11:57 AMThe "refactoring" I referred to was a class wrapped around a collection of A, let's call it W. All of the methods in W used A, then I wanted to change them to use B. So I guess the behaviour of W did change: it takes/returns B instead of A. This is not "refactoring W" in the correct sense, you're right. If I had just changed the insides of A so that A is now A', then the behaviour of W would not have changed, since the change is encapsulated in A. But if I'm doing all of that that inside an API without changing it, then I'm refactoring beneath the API, right?. In that sense I was refactoring my application, above. I guess it depends on your granularity level and what you refer to. It's a good thing to watch out for though, thanks Keith. » Posted by: Ryan at August 10, 2004 12:14 PMSee It is truly baffling that refactorings and indeed the very idea and first implementation of a refactoring browser all come from Smalltalk where, as you say, "refactoring is just a string match". I wonder how that could be? I wonder if you could be wrong about all the advantages of static type information for refactoring, and about how in Smalltalk you only have a string match? » Posted by: at August 10, 2004 02:45 PM"refactoring is just a string match" Aren't generics already supported? or are you just running your jvm a few versions behind the current? » Posted by: Kibbee at August 11, 2004 08:21 AMGenerics are supported in Java 5 (1.5), which is still in beta. http://java.sun.com/j2se/1.5.0/ » Posted by: Ryan at August 11, 2004 08:23 AMstill in beta, damn they move slow. i think i heard about that 6 months ago » Posted by: Kibbee at August 11, 2004 06:33 PMIncidentally, the parameteric types (generics) in Nice don't require a new JVM, and local type inference reduces the verbiage: let list = new LinkedList(); or let List<int> list = new LinkedList(); instead of List<Integer> list = new LinkedList<Integer>(); "refactoring is just a string match" This is just pure nonsense, as anyone with just the patience to do a Google search and read a little about the Refactoring Browser, for example (Johnson, et al) would see. » Posted by: at August 12, 2004 09:18 PMstatic typing has one advantage that i truly appreciate: it finds errors at compile time that otherwise would happen at runtime, where they would be much more dangerous. saying things like "i don't make mistakes" sounds like famous last words to me. i really don't see the advantage of dynamic typing: to me it seems like a powerful tool that is almost never useful in practice but can lead to dangerous mistakes at the same time. like multiple inheritance in c++. i.e.: i have never seen a real world example where i would have wanted dynamic typing. it would save me a cast here and there, but, to be honest, that costs me about 1 second each time, especially using Eclipse and auto-fix. » Posted by: nikster at August 13, 2004 03:36 AMnikster: I agree, I don't see the benefits yet either. It's more like "trust us, you'll see when you get there". I haven't seen a good example yet. » Posted by: Ryan at August 13, 2004 06:39 AM |