I was just reading over on Dave Ferguson's Blog about his debate over whether or not to use some undocumented features of ColdFusion (specifically, using the underlying Java objects that power core ColdFusion data types). This is an interesting debate, and one that I have struggled with myself. As with all complicated things, I often find that my true feelings on a matter can be more easily found when I port the situation into a slightly different problem space to which I have no emotional attachment. This way, I can separate emotion from reason and see what my gut is telling me.
But first, what are the reasons one might have against tapping into the underlying Java objects of ColdFusion? The biggest concern raised is the issue of forward compatibility. If a feature is undocumented, there is no guarantee that it will be available in the next release of ColdFusion. This is one of those concerns that immediately sounds very persuasive. Oh my god! what if all my systems start to crash when I upgrade?!? It's going to cost gagillions of dollars! What will my client's think! It will be crazy - dogs and cats living together - total chaos, right?
Let me ask you this, though - have you ever upgraded a production server without first upgrading your development environment and testing all your sites locally? Could systems really ever crash in such a way that it actually causes your client's a lot of money or public shame? I believe that the development life cycle should prevent this from ever happening. Anything that could go wrong should be discovered long before it is even put a in a position to cause problems. So, let's get rid of that "chaotic fear factor;" no problems are just gonna pop up out of no where; hundreds of clients are not going to start frantically calling you all at the same time wondering why their sites are down.
Ok, so please continue reading knowing that what ever happens, it will be slow and it will be controlled and it will be calm.
Now that we are calm and relaxed, let's take our situation and port it over to a less emotionally charged problem domain such that maybe we can think more logically. Let's take a look at ColdFusion User Defined Functions (UDF). When you build a user defined function for ColdFusion, do you ever feel bad? Do you ever feel like you are doing something wrong? Absolutely not; the ability to create user defined functions is a wonderful and documented feature of ColdFusion that makes development much easier. But, just because it's documented, does that mean that it guards us against future compatibility issues? I can tell you first hand that it does not. When I upgraded from ColdFusion MX6 to MX7, dozens of my applications had UDFs whose name conflicted with a new, built-in ColdFusion function. Not only did I have to change the name of the function, I had to search through my code and change every reference to it.
Whether or not this has happened to you, this kind of issue is much more likely than you think. As a though experiment, let's take a look at the security functions that are new in ColdFusion 8:
These aren't far-out function names. These function names are very logically thought out and appropriate to the context in which they are used. In fact, IsUserLoggedIn() is such an obvious name that I would guarantee that there were many folks out there with UDFs of the same name whose ColdFusion applications are now not forward compatible. ColdFusion, in general, follows such a logical naming scheme that it almost creates a higher likelihood of you authoring UDFs that are NOT future proof. Imagine if you wanted to create a list function that would take a list and reverse it, what would you do? You'd see the trend in list naming and call it ListReverse(). The problem with this is that it fits so nicely in the traditional ColdFusion naming scheme that if ColdFusion ever added a function that did this, it would most definitely use this name, making your future ColdFusion application not compatible.
Now, let's take one foot out of ColdFusion and talk about solutions that work with third party applications. What if you build a solution in ColdFusion that works with Microsoft Word 2003. Whose to say that that solution will work with Microsoft Word 2007. In fact, from what I have heard, Microsoft Office 2007 got such an overhaul that many products that worked with Office 2003 no longer work with Office 2007. Does this mean that the original solution should not have been built? Do you think ColdFusion developers were sitting in their seats thinking to themselves, "I have an awesome ColdFusion idea that works with Office 2003, but it might not work with Office 2007 or other future iterations... I should probably scrap the whole idea because if anyone ever upgrades this will no longer be compatible."
When you take the context slightly out of ColdFusion, it sounds ridiculous, right? No one really thinks about third party compatibility issues, but is it any different? You're using features of a language that are not guaranteed to be forward compatible.
What if we leave the ColdFusion domain all together? Let's talk about laptops for a second. Many people go to and from work with their laptops; and, since laptop power supplies are so heavy, oftentimes, people will get a power supply to leave and work and one to leave at home. Now, laptop power supplies are not universal. In fact, they are almost comically NOT universal. It seems that almost every single new laptop that comes out has to use its very own power supply. Even though this is the case, do you think people worry about it? Do you think Joe Computer Guy ever thinks to himself, "Oh man, my life would be a lot better if I had a power supply at home and at work, but if I ever buy another laptop in my life, that power supply will probably not be compatible - I better just drag my power supply to and from work in case I need to get a new laptop soon."
Again, another totally crazy-ass thought, right?
I think you can look at dozens of different situations in your own life and realize that the fear of forward compatibility almost never comes into light when making decisions. So, what is it about undocumented features in ColdFusion that make people react to emotionally? Let's examine some potential thoughts:
1. Undocumented features might not be compatible in the future.
Yeah, true. But, like I pointed out above, incompatibility won't just happen because of your usage of underlying features. It could happen with emerging function conflicts or even out-of-your-control third party upgrade issues. How is that any different?
2. By using only documented features I am taking steps to ensure that my applications will be future compatible.
Yeah, I'm sure that's what people were thinking when they made an awesome UDF named IsUserLoggedIn(). Unfortunately, their effort to use only documented features did not work out so well for them. And, who's to say that future versions of ColdFusion will be backward compatible at all? I have heard that some people are pushing for a version that is not backward compatible. If a switch like that happened, all your effortts would be moot.
3. If compatibility changes, it will cost millions of dollars and months to fix all the code.
Really? How many undocumented features do you think you are using? Let's pick something really common - let's say you were using the underlying String.Length() method rather than Len( String ). This could be used on potentially every page of your application, right? Not a crazy thought. Even if this was in, oh, let's be generous and say 5,000 pages. I think this is way more pages than most any application has, but heck, let's play hard. Now, let's go crazy and say that an extended Find takes 10 minutes to execute and that each of those changes takes two minutes to switch over to a compatible format (which is extremely extremely generous). That means that making all of those changes would take 166 man-hours. If only one person did this, it would take 20 days. If three people worked on it, it would take 6 days.
For a 5,000 page application, which is unbelievably large, it would take a few people just a few days to fix the entire application. Is that such a nightmare? Really? Is that even such a huge cost? I don't think so. And, if you take a much more likely situation, let's say a 100 page application where the issue is on every page, it would take one person maybe 4 hours to fix. Four hours is nothing - I've spent more time debugging documented code, so don't even tell me about the cost of fixing undocumented features.
I know it is an oddly emotional subject, but I really just can't see what logical reasons people have against using undocumented features. If you are using something that makes your code better / faster, why shouldn't you do it? Especially, when the time/cost of future change is really not that significant, even on absurdly large projects.
You know what seems ironic to me? The fact that people who use "best practices" in programming seem to be the most adamant about NOT using undocumented featured. At first, this might make sense, but think about what these best practices are - cohesion, low coupling, encapsulating what changes. People who have very well organized code and a very high amount of code reuse would be the ones least hurt of issues of future incompatibility. A programmer who has to change a piece of functionality in one place is much better off no matter what than a person who needs to change a piece of functionality that is duplicated in 50 places, and yet, it is the less experienced, spaghetti coder who I think is more willing to take a chance. That just seems ironic and funny to me - the people who have the tools to absorb the hit are the ones least likely to try.
So anyway, that's my little brain dump on using undocumented features. I'm not saying you should run out and use as many as you can; I'm just saying that if you find one that you feel makes your programming better, use it without worrying - it's no more dangerous than anything else you do.