Wednesday, July 5, 2006

Duck Typing: Stop the Insanity

If you pay attention to the ColdFusion blogs at all, or if you were at CFUnited, you're well aware of the new-found duck typing craze in ColdFusion land. While I agree with some of the sentiments behind advocating duck typing, as with most things that become a veritable feeding frenzy, there's quite a bit being lost in the insanity in my opinion.


First and foremost, just because you can do something doesn't mean you should. Let me state that again and extend it a bit. Just because you can do something doesn't mean you should, and it certainly doesn't mean it's appropriate to do it all the time. My fear with all the blog postings I've been reading the past few days is that people will take on an attitude along the lines of, "Typing? Who needs it! This is ColdFusion!" Personally I think that's exactly the wrong approach.


Let's stop and think about why typing exists in strongly typed languages such as Java. Yes, I know ColdFusion isn't Java, but kindly stick with me for a moment. Typing exists in Java for numerous reasons, not the least of which is that type checking makes for safer software. Why? Because in Java if you're doing something wrong, either on purpose or inadvertently, the compiler won't let you get away with it. If an object's expecting a Person to be passed in as an argument and you try to pass it a ShoppingCart, that simply isn't going to fly. No worries about weird runtime errors based on typing because you can't even get that far. From my years as a Java programmer I'll say this much: once you get the darn thing compiled, you've won well more than half the battle. Java feels solid precisely because of this aspect of the language, and many other languages both before and after are strongly typed for many of these same reasons.


Is dealing with strong typing a bit of a headache? Sure, particularly when you're in a situation where duck typing is actually necessary. Re-read that last part. "... where duck typing is actually necessary." Now given the fact that there isn't, strictly speaking, a way to even do duck typing in Java, and there are plenty of Java applications out there running just fine without it, "necessary" might be a bit strong in this case. So let's downgrade that to "... where duck typing sure would come in darn handy and I'm doing it because I know what I'm doing and actually mean to remove type-checking and all the benefits that go with it." One of the ways Java addresses cases in which duck typing would come in handy is to use interfaces, which--and the discussion of interfaces is a topic for another blog post altogether--ColdFusion doesn't have. (As an aside, BlueDragon 7 adds a cfinterface tag, and it was rumored at cf.objective() that CF 8 may add interfaces as well.)


Now back to ColdFusion. As many have pointed out over the past few days, ColdFusion is not Java. Fair enough. What I take issue with is the extension some folks seem to be applying to this statement. Specifically I find statements such as "ColdFusion isn't Java, so don't worry about typing at all" extremely problematic. ESPECIALLY if people are new to OO and they're bypassing the proper learning of OO and jumping straight to going typeless everywhere in all their applications, this is utter madness.


Granted, because all the type checking in ColdFusion is done at runtime, we don't get the same compile-time checking that Java developers enjoy. (Take "enjoy" with a grain of salt there; the Java compiler is a rigid taskmaster yet we are forced to seek its approval and are generally elated when we receive such approval via a successful compilation.) That doesn't, however, completely negate the value of typing in ColdFusion.


First let's think about the development process. ColdFusion checks type at runtime, but during development, when you change a file and fire things off again, behind the scenes things are getting compiled and subsequently they are immediately executed. So this is really a compilation step with automatic execution thereafter. Not so different. If you're passing something an object of a type it's not expecting, ColdFusion throws an error. During development you may absolutely want this to happen, and it can save you some headaches because you get no further than CF saying, "Hey pal, wrong object type. Try again." This can be great for debugging purposes.


Next, let's think about deploying an application to production. Do you care about typing once the application is complete, has been thoroughly debugged, and you're absolutely, positively sure everything's going to work correctly? Probably not. You don't really care about it at that point in Java either. Once all the bugs have been ironed out you know the correct types are being passed, so conceptually at least, it probably no longer matters. Of course there are special cases where it might matter, such as if you're writing an API and people interact with your API by throwing objects at it, a good old-fashioned "wrong object type" error might be better than something that could be much harder to debug.


The other advantage of duck typing people seem to be going nuts over is performance. In Java, type checking is done at compile time so even if you could do straight duck typing in Java, there's no performance benefit. In ColdFusion on the other hand, type checking is done at runtime, meaning this is an additional step ColdFusion has to perform. No huge surprise then that if you don't make ColdFusion perform this additional step, things are going to be faster. How much faster? Depends on the application. My real concern here is performance gains ... at what cost? Duck typing for the sake of performance should only be done in very specialized circumstances, and I'll probably have more to say on this point soon.


Before I ramble further, I'll cut to the chase and summarize by saying that duck typing is darn handy when you need it, but eliminating typing altogether because it's the new, hip thing to do, or because you think it's the top-secret weapon that will make your CF apps lightning fast, is a big, big mistake. If you listen to ColdFusion Weekly you'll probably recall the call we had a couple of weeks ago asking for our thoughts on the Hal Helms and Jeff Peters Out Loud episode where they discussed "GroupThink." Duck typing is another case in point in my mind. Please, please, please, for the love of the OO gods, think about what you're doing when it comes to duck typing. Don't skip typing because all the cool kids are doing it.


So where do I think this is all going? I hope that we're in another Hegelian phase of our collective development knowledge. Thesis: ColdFusion has a type attribute now, so use it. Antithesis: forget typing--duck typing all the way. Synthesis: use duck typing only when you need it. We're currently still in the antithesis phase which is why I thought it was a good time to do my own personal brain dump on this topic.


I'll conclude with a few bullet points that you can use as food for thought.




  • Duck typing is great when you need it, but in the vast majority of cases you care about an object's type (at least philosophically).


  • Duck typing for performance is a very bad reason to do duck typing, except in specialized circumstances.


  • Duck typing throughout your application can make development and debugging much more of a hassle.


  • Just because ColdFusion checks type at runtime doesn't entirely negate the benefits of typing.


  • OO is to a large degree about discipline. Don't duck type at all until you've done it the "right" way for quite a while.


  • Learn Java. I'm not saying learn it to the point of expertise, but play around with Java and learn how Java thinks. You have to know the rules before you can intelligently (and hopefully judiciously) break them.


  • Make up your own mind. Don't duck type until it makes sense to you to duck type, and even then, only do it when you need it. (Yes, I know I repeated that point, but it's and important one.)



That's all my quacking (har har har) on duck typing for now.


Comments


Matt - Great article. But what I think some of us need, is a real BASIC tutorial on duck typing. This whole duck typing, OO, etc. talk is like listening to the Gods talk on Mount Olympus, but us little people down the mountain don't understand.

Examples of duck typing and the explanation of what an Interface is. WTF is and interface?



Well said Matt. I'm always amazed at how the 'sound bit syndrome' gets ingrained into peoples brains. The brief exchange about how Duck Typing **in specific portions of 2 frameworks** significantly increased the performance of the frameworks got turned into 'Duck Typing = Fast Code'. Sean Corfield had a nice follow-up on his blog about this same issue and addresses the performance issue as well.

BTW, re-listen to Helms & Peters Out Load's "7 Habits of Highly Ineffective Programmers" podcast. One of the 7 'ineffective' habits was putting too much weight on performance.



Hi Matt,

Great post. There is only one thing I'd add. Once you've learnt Java, go play with Ruby!

I agree 100% that duck typing is a specific, advanced solution to a specific problem. For me the best thing about duck typing was that it forced me to spend the time to really "get" interfaces and nulls - and the implications of not having them.

If you have to do duck typing for performance (pretty unlikely), you can do it as a production build stage with a Regex so you can keep better documentation and still have the benefits of the slightly earlier and easier to debug errors that psuedo static typing provide during development and testing.

However, once you've done all of the above, start to really play with mixins. I think they're as dangerous as a goto - but really - the ability to copy and rename methods at runtime like any other variable?! Dangerous - but very cool indeed!

Best Wishes,
Peter



For the person who asked, Rob Gonda posted a good list of links on Duck typing recently:
http://www.robgonda.com/blog/index.cfm/2006/7/4/PostCFUN-Must-read-links

I'd personally recomment Vy a Duck (and getting a subscription to Fusion Authority Quarterly Update - it looks like being quite a magazine - especially with articles on cool stuff like flash forms :->).

Also, as a practical matter, unless you've had a problem with the lack of interfaces or nulls in CF, you probably don't need to worry about duck typing. It's like any design pattern - very hard to understand until you come across the forces that drive it in your latest app. And then it becomes an obvious solution to your real world problem!

Best Wishes,
Peter
Best Wishes,
Peter



Matt,

I agree 100% with your article. I worry that all of this discussion will cause some developers to abandon typing altogether, without understanding what they are doing or what problems it can cause.

Also, there's a point I've made before that is worth restating: with typed parameters, type mis-match exceptions are thrown at the START of a method. With duck typing, exceptions are thrown in the body of the method when the offending line of code is executed. THIS COULD BE IMPORTANT! Consider the case where a method commits some atomic action: it must either all succeed or all fail. Sure you could do all kinds of nasty type checking by hand and use liberal amounts of try/catch blocks, but typed parameters do it for you.

Plus, typed parameters provide a bit of self-documentation that I think is pretty valuable.

Bottom line: I think we use typed parameters in CF *unless* there is a clear cut reason not to. Don't duck type just because its the going fad.

Seth



Just out of curiousity, why are so many cf developers trying to make cfml into java, when it isn't?

I mean if you like java, then code in java. I am not saying cfml doesn't have room for improvement, but java and cfml have two seperate and different purposes.

And what exactly is duck typing?



Hi Matt:
This is the best posting on the subject I've read so far (and, yes, have read quite a number of them in the last few days).

Good work.

--
Adam




Craig--this isn't an issue of Java vs. CFML. This is about writing good, solid code, which in my opinion in the vast majority of cases means you should type your objects. That doesn't mean I'm trying to turn CF into Java, it means that I'm taking full advantage of what type safety does exist in the language.

If you don't know what duck typing is I'd suggest wikipedia as a starting point:
http://en.wikipedia.org/wiki/Duck_typing

Judith Dinowitz also has an excellent article on Fusion Authority:
http://www.fusionauthority.com/Techniques/Article.cfm/ArticleID:4588

That should help put the discussion in context.

As for the question on interfaces, I'll try to post again on that topic at some point, but again wikipedia might help in the mean time:
http://en.wikipedia.org/wiki/Interface_(computer_science)



Matt,

I am honored to have you lead our CFUG. Well done, and I fully agree.

Mike.



In a conversation I had with Joe Rinehart at CFUnited (at least I *think* it was Joe!) he mentioned that his approach wasn't the nuclear option of just stripping out every single "type" and "returntype" as was suggested by at least one presenter at CFUnited. His suggestion was to find particular bottlenecks, and if ducktyping can be a benefit in those places, then by all means implement it. The example he gave was in the XML parsing of Model Glue in which ducktyping gave considerable gains. This is not a black and white subject in my opinion, and I don't believe the answer is simply to strongly type *or* duck type. There is a middle ground.


Amen!


Well written (golf clap). You went to university didn't you.?! By the way: 'Typing: Why do you care' (the name of my new book... on bookshelves when coldfusion becomes typed, (that's 'never' folks) classic...

There's better ways to do things, yes sure, so go do them and stop being so flipping academic.

Coldfusion is fun, that's why academics want to change it. It doesn't fit their limited mindset. Everything has to be definable (or typed) or it's wrong.



Chris,

No offence, but that was a poor troll, a very poor troll indeed. I suggest reading this and trying again tomorrow.

Cheers,

Kurt



Matt, good summary. I don't think many people advocate taking out typing entirely (myself included) but for people new to the subject I think it was good to reiterate that point. And I think before people try tackling a subject like duck typing they should first gain an understanding of object oriented programming, object oriented design, and design patterns - just some advise for the people out there new to the subject.

Zach



Another thing to keep in mind when considering optimizing some code by using duck typing is to remember that is likely that the next version of CF will likely correct some of the speed advantage currently provided by not having types.


Java can do Duck Typing, as of Java 1.5.

Please see Duck Typing in Java and no Reflection



I strongly protest against the term duck.

I am a duck myself and al my life i am mocked at.

See for your self

LOL



Matt,

I, like you, am a big fan of static typing in Java where we have a compiler to check errors and can achieve some decent degree of type safety. When I began advocating for duck typing, it was not for performance reasons, at all. In fact, I had no idea that duck typing would result in performance gains.

Instead, I advocate duck typing because (a) a pseduo-statically typed language generates almost no benefits and (b) without some form of multiple typing (either multiple inheritance, interfaces, or something), static typing will force people into bad, convoluted inheritance chains in order to gain the benefits of polymorphism.

So, I *do* advocate duck typing extensively. The benefits are minimal and the risks of forcing architects into bad design is great.



Errr...I meant the benefits of pseduo-static typing are minimal, etc.

No comments: