Last week, I shared my reluctance to blindly accept the abstractions found in languages and frameworks like Ruby on Rails. This sparked quite a bit of discussion on and offline, as well as more than a few notes from angry developers. There were lots of pish-tosh-type comments, such as, well then, why I didn't write my own operating system? Or that using curl was somehow the same as using Capistrano to automate deployments.

Let's unbunch our collective Huggies and take another look at this, shall we?

[ Fatal abstraction: A bottom-up view of high-level languages | Work smarter, not harder -- download the Developers' Survival Guide from InfoWorld for all the tips and trends programmers need to know. | Keep up with the latest developer news with InfoWorld's Developer World newsletter. ]

First off, let's set a baseline. If you choose to be so obtuse as to compare my mistrust of high-level development frameworks with the use of a command-line database client, we're probably done here. There's no real discussion to be had with that mindset.

I'm clearly not talking about reinventing every wheel, writing my own database, or any such nonsense. I'm talking about languages and frameworks that completely obfuscate what's actually happening below the surface. Their ideal is to hide all the machinery and present a slick, glossy interface to working with those elements. If you look at it one way, you can definitely write database-driven apps without ever really looking at or touching the actual database.

In theory, this might seem really neat. I mean, it does make things easier and sleeker. If I need to perform certain low-level functions, I just look up how the developers of the framework accounted for those low-level functions, then I use their interface -- easy-peasy.

But when there's nothing in the framework that does what I need it to do, I'm suddenly abandoned. My carefully constructed sleek interface now needs some ugly real-world code bolted onto it to make it work right. That particular wart is likely to join several others during the course of the development, and I will end up with a hodgepodge of code, which was ostensibly the very thing that framework was trying to prevent.

This isn't necessarily anyone's fault. Nobody can predict the requirements of a given development project with 100 percent accuracy. That's sort of the whole point of languages like C and Perl. They can be used to do just about anything because they offer tools, not interfaces. You can build anything you want with a fully stocked toolbox, but you'll have a hard time making a bookcase if your only tools are a screwdriver and an awl.

That might be a bit of an oversimplification, but it's definitely true. There have been and will be many times when small problems become huge due to the failings of the framework. As reader Ramon S. put it last week: "How many times did I hear from developers, 'We cannot do this because the framework does not support it.' Seriously?"