Thursday, May 29, 2008

Aging codebases, a postscript

Ron Avitzur's comment on my post wondering aloud as to whether code can age gracefully done tickled my brain. I mean, I think about code a lot. I think about software and making software a lot.

But for some reason, I hadn't ever pondered how truly strange software is - if you look at it a certain way, it's never truly broken. It may be old, it may be ungainly, but it will always do something.

Sure, the hardware that it ran on may disappear or cease to function and the compilers may evaporate... but that doesn't mean that the code's broken. It just means that you've got a little work ahead of you porting that software to the latest and greatest hardware and toolchain and bingo bango your software's back from the dead.

Of course, there's always the question of "should we?". Times move on and inevitably reach a tipping point where maybe it makes sense to let that sleeping codebase lie.

Steve McConnell refers to this as a "doghouse problem" - when it comes to building a doghouse, everyone has an opinion on what color to paint it, what the roofing tiles should be, the exact dimensions, yadda yadda because it's a problem so eminently tractable that we can easily wrap our heads around it. Hell, it's within the realm of reason that we could build it ourselves. We have a pretty good idea of what it'll cost to make and how long it'll take.

But ask us to price the cost, materials, resources and time required to build a skyscraper and... good luck on estimating that one. How hard can it really be though? They're both buildings, right?

A couple of real-world buildings brought this into clear focus for me.

First is an old mill building not too far from where I live. For the years I've been here, it's been uninhabited - a hulking, crumbling mess of a building. 100 years ago, I'm sure it was a bustling center of commerce, an economic powerhouse. Now it's gone past creepy and into sad. It's being demolished to make way for... I don't know. Probably another drug store or something.

(zoom on the crumble)

Second is This Old House, or what's left of it. There was a house there once, nothing here now but the bones of the old building rising like so many dinosaur bones from the ground.

(check them bones)

Either one of them could be broken down as much as possible to be built back up to work again, but it's the house whose bones will remain in place while the mill's ground into the dust. Looking at it, the possibility of fixing it piecemeal doesn't even enter into your mind - it's over a hundred years old, frigging brick and huge. The house, on the other hand? Over a hundred years old, but the frame and chimney are still sound - we can rebuild around them, putting the walls and stairs and windows in different this time.

When looking at open source projects, it's not uncommon for one of the mentioned features to be their "clean codebase" - on some level, this is kind of laughable because who but a geek gives a shit what the code looks like as long as it runs well enough and does something useful for you?

On another level, it shows that there's people who have taken pride in their work, that fix broken windows, and have a vested interest in making sure that a year from now, it will have crumbled less than that mill building.

Think about building something that will stand the test of time and it just might. Make it concise and useful enough and who knows? Its framework just might live a decade or so.

I hope to someday build something so good that I won't be able to hear the lamentations of the developers responsible for supporting it because I'm busy watching Wheel of Fortune too loud or whatever it is that incredibly old people do. Did I mention that I'm watching The Wheel in my rocket car? Because ideally, I'm incredibly old, reasonably well-to-do and the future finally delivers on its promises.


I biked by the house again earlier this week. Nothing remained.

I still hold out hope for a rocket car-filled future.

Monday, May 5, 2008

SQL Server, we need to have a talk

So I'm working on normalizing the database the other day.  I want to move some columns from a table that I'm about to make vanish to another table and I can't remember the syntax for it.  I should have hit up The Google (the SQL syntax for adding tables/columns to tables really is dead simple) but instead I was extra lazy and fired up the table designer inside of SQL Server Management Studio and scripted out the changes to the tables.

I finish that up, finish modifying the stored procedures, everything looks good.  I run the SQL script, fire my black box tests against it.

Hmm.  Things ain't working right.  The column that I just defined to hold a decimal is causing problems.  I check my stored procedures to make sure I'm not doing anything insane, check my business logic to make sure I didn't bork anything there, it all looks good.

I take what I'd just scripted and distill it down to its essence.

table scratch
percentage decimal (18,0)

into scratch
values (0.5)

select *
from scratch

Not-so-curiously, the scratch table now contains a lone value of 1.0.

When you look at it, it's obvious what went wrong here - I just defined a decimal with zero digits of decimal precision.  Or, as I like to call it, a fucking integer.

I obviously biffed in the first place, but this left me scratching my head - why on earth would you make the default for a decimal (effectively) an integer?

As an added bonus head scratcher, there's no warning about the loss of precision/silent rounding when you store the value in there.  I don't know what should happen there (do you want an exception because of that sort of thing?) but I do know that it rhymes with "leaky abstraction."  I'm not an RDBMS guru, people.

Times like these, I understand why it's regarded as best practice to treat money as two integer values (dollars and cents!) - databases are a bit funky when it comes to storing out your decimal values.