Archive for January, 2007

Prototype: Sliced Bread, or Devil’s Spawn?

Wednesday, January 24th, 2007

People like to bitch about prototype.js, usually because it extends Array and Object in ways that are incompatible with a lot of existing code, including other add-on libraries. I fully agree with this criticism, but I have yet to find another alternative. Prototype fills a very important niche in the javascript ecosystem: a small, simple, succinct library that lets you do 95% of the things you’d want to do in a modern Ajax app.

Here are some other javascript toolkits. Mind you, these are not all trying to provide equivalent functionality. But I think it’s fair to include them all on the same list, because they are all trying to provide tools to make Javascript a more powerful language, and one more suitable for creating the types of web apps that most people want to make these days.

Mochikit is the one I’m most familiar with. It’s a great toolkit, and kind do all kinds of cool stuff that Prototype doesn’t. But, most of the time I just want to do a simple ajax call, or really minor DOM manipulation. Mochikit just feels like massive overkill in those cases.

This could be intention - Mochikit is supposed to be a heavy-weight solution, which is what you need sometimes. But being heavy-weight means that it’s got that namespaced, heavy-handed, verbose feel that I associate with Java and Python. For example, look at what you need to do to make an Ajax call in Mochikit:


var deferred_obj = MochiKit.Async.doSimpleXMLHttpRequest('/some/url');
deferred_obj.addCallback(updateDiv);
function updateDiv(result) { $('mydiv').innerHTML = result; }

Compare to Prototype:


Ajax.Updater('mydiv', '/some/url');

Aside: I’m no Mochikit expert, though I’ve used it on a few projects. If someone has a better way to write the example above, please leave a comment.

Aside 2: The technique above could more correctly be called AHAH.

You could go on and on about how Mochikit is more powerful, that its deferred object framework offers all kinds of possibilities for unusual ajax calls and other kinds of javascript magic. All that is true. But then there’s the fact that, 99.9% of the time, all you want to do is fire off an ajax call and update a div, or maybe call a function to process the results.

Easy things should be easy to do. When a “powerful” tool makes the easy case hard, I get suspicious. For code, easy means easy to write (which means, easy to remember: I don’t want to reference the docs every time). But it also means easy to read and understand later, and for that you want to be succinct and explicit. Reading the prototype code I can see that the line has something to do with ajax and something to do with updating. Simple and unmistakeable.

The best tools are ones that make the easy case easy, but still offer the power to do more complex and unusual things if you want to dive in a bit deeper. So I guess you could make a Prototype-style wrapper for Mochikit, with simple helper classes like Ajax.Updater to export a succinct interface to the powerful concepts that Mochikit offers, and that should be the best of both worlds.

As for Prototype, I’m certainly not enamored with it. In fact, I’m really hoping for is some other small library will come along and fill the same niche as Prototype, but do it better. In the meantime, Prototype is the best in that niche, so I’ll keep using it.

“Firefox Is Just a Browser”

Tuesday, January 16th, 2007

In my last post, I said that Firefox is “the best thing that ever happened to the web, maybe even the best thing that’s ever happened to software in general.” This off-the-cuff remark seemed to generate more buzz in the comments and on reddit than my main point.

xkcd nailed the issue with perfect humor. Everyone’s going crazy for Firefox, but come on - it’s just a browser. Right?

Well, yes and no. Yes, Firefox is a browser, and in many ways only an incremental improvement over its immediate ancestors like Netscape, IE, and Opera. But it’s also much more than that. Firefox is the enabling technology in a whole new world of software development.

I doubt I need to expound on the virtues of web applications over locally installed apps to anyone that is reading this. But really though, take a moment and think back to what software was like before web apps took over. Incredibly long development cycles, endless installation headaches, viruses, hardware and operating system incompatibility. Being forced to develop with whatever language(s) and tool(s) are available on your end user’s operating system was once the norm, and it gives me the cold sweats just to think about it now. And CDs, in a box? We were such barbarians.

In short: desktop apps sucked. They sucked to make, they sucked to use, and they sucked to support. I’m giving myself ulcers just reminiscing on those days.

Firefox is just one small piece in the web application software revolution. But because it is such a visible piece, it serves as a rallying point for all of us championing the revolution. It solved not necessarily the hardest piece of the puzzle, but the piece that software geeks were probably least equipped to solve: marketing a thin client to the masses.

It’s the bootstrap piece. With that in place, everything else gets pushed back to the server, and software geeks can focus on what they are extremely well-equipped to solve: everything else, which is all technical and design issues.

The beauty of it is that Firefox itself will become a less critical component as time goes on. It served as an emissary, a flag bearer for the technical and political elements that drive this revolution: standards compliance, markup separated from content, specialized open formats like RSS, PNG, and SVG, and client-side scripting powerful enough to do almost everything one might want an application to do. But having led the way, others will follow. And we don’t need Firefox, specifically; we need a standards-compliant browser. Pretty soon all browsers will be that, because they have to be, or be left behind.

As it turns out, replaceability is one of the guiding principles of this new generation of software. Components that can be swapped out like legos. Nothing in the web application stack is unique or can’t easily be replaced with a comparable product. Apache rules the web server world, sure, but Lighttpd is a perfectly suitable replacement. Red Hat Linux ruled the OS world as far as servers and developer workstations for a while, but then it started to suck because of the RHEL/Fedora split. Faster than you can say “lickety-split”, Red Hat was off the map and Debian’s offspring Ubuntu now dominates. Any other major component you can think of is swappable: databases (MySQL, PostgreSQL), languages (Ruby, Python, PHP), application frameworks (Rails, Django, Nitro, Symfony), shells (bash, zsh, dash) - the list goes on.

This might have been the nastiest bit of sucking from the old style of software development. In that world, you had major components that couldn’t be swapped out. Microsoft was king here of course, but they weren’t the only ones: think of Oracle, Sun, or Adobe. This control was great for the profits of the company in control of the technology, but total suck-land for everyone else in the long run.

Firefox is not just a browser; it’s a software platform. Once upon a time we spoke of developing software for DOS, or Windows, or UNIX. Now we develop for the web; and by all rights, Firefox is the web. Not by virtue of its market share, which remains a small minority; but by virtue of its leadership position within that market.

Or you can say Firefox is just a browser, as long as you also say that Linux is just another unix derivative, Microsoft Office is just another office suite, Google is just another search engine, and Rails is just another application framework.

Revolutions rarely are really something completely new. They’re always “just” an incremental improvement over whatever existing before. But that increment can be enough to launch a whole new paradigm. Firefox is one piece of a larger whole which is going to - nay, already has - change the world.

Go Ahead, Do The Big Rewrite

Thursday, January 11th, 2007

Many experienced developers caution against the Big Rewrite. Perhaps the most famous of these is Joel’s adamant proclamation that the Mozilla team’s decision to rework Netscape from the ground up was “the single worst mistake” that a software team could make.

Although I agree with Chad’s arguments and to a lesser degree with Joel’s, I can’t help but to notice: what Joel called a huge mistake turned into Firefox, which is the best thing that ever happened to the web, maybe even the best thing that’s ever happened to software in general. Some “mistake.”

Ok, ok. So most of the time the big rewrite is a bad idea. Mozilla got lucky, or tried really hard, or it doesn’t count if you’re an open source project, or something.

Except that I’ve done several big rewrites of commercial applications in my software career, and every time it has gone very smoothly. In all cases the end users have been pleased, and I and the other developers find ourselves saying “We should have done this ages ago!”

In fact, Bitscribe is currently finishing up one of these right now. The application being rewritten is one of those sprawling enterprise apps with countless nooks and crannies of functionality. Written in a blend of PHP, Perl, PL/PGSQL stored procedures, and C++ (GTK 1.0, baby!), it dates back to right around the turn of the milenium. So not utterly ancient, but plenty has changed in the software world since then. The rewritten application is 100% Rails.

Everyone involved with the project just couldn’t be more pleased, from what I’ve seen. It’s been a lot of hard work, sure, but the benefits are massive. Developers are energized and excited to be working with the latest tools, and throwing out years of accumulated developer debt. (The legacy app had been maintained by a variety of different companies over the years, so you can imagine what the code looked like.) The client’s staff is loving the shiny ajaxified interfaces. And the client’s management (you know, the people who sign the checks) are seeing a whole new world of software unfold before them, and seem very aware of the efficiency improvements that will come with it.

There was a benefit that we didn’t anticipate, and it’s turned out to be one of the most useful. In the process of rewriting we’re not just porting code; we’re rethinking the design. The technical design of course, but also application design. It turns out that the wisdom the clients had gained from years of production use of the legacy application pointed to many insights on a streamlined design. We’re able to provide the majority of the functionality of the original app with a fraction of the complexity.

And not just code complexity, but user interface complexity. When all is said and done, the client’s training costs for new staff will be greatly reduced; there’s much less likelihood of entry error; and the application matches their business process more closely. Et cetera.

So I’ve never had a rewrite go badly. But maybe that’s because I’m inherently cautious and skeptical about rewrites. I lean toward waiting a bit too long, rather than doing it a bit too soon. So then by the time we go to do it, it’s really overdue.

Raganwald says “And you’ll need to be 100% sure your team has the horsepower to get the job done and is going to use a process that can handle the load.” Maybe that’s why it’s gone well for us; Bitscribe has massive developer horsepower, and massive focus on process. And even for us, there’s been lots of strain on the team doing the rewrite.

I’ll admit that there’s a unique kind of pressure that you get in this situation. It’s not like the ordinary pressure to meet software deadlines. I think it’s that sense that you can’t turn back. You don’t want to fix bugs or add features to the legacy code, but the client needs those changes so that they can do business. So then you have to press on ahead and try to get the new version workable as quickly as you can. And as Chad points out in his essay, there are seemingly endless little bits of functionality in the original app that need to be provided in the new system. It’s not a kind of pressure I’d be willing to bear most of the time, but it can be worth it when an app is really due for a bottom-up overhaul.

And let’s face it, you’ve gotta rewrite sometime - no software system can run forever, and the cost of running even a marginally outdated app can be tremendous. I guess the trick is just picking the right time to do it - and then having a healthy fear of just how big a job it really is. The moment you think it’s going to be easy, that’s the moment you’re digging your own grave. Be scared of what you’re facing and you may just have a chance.

Why Do We Still Use Relational Databases in an OO Era?

Tuesday, January 9th, 2007

Object-Relational Mappers (ORMs) have been a hot topic for, oh I don’t know, a decade now. Mapping an object-oriented data set onto a flat relational schema is unexpectedly difficult. Inheritence, polymorphism, and even simple deviations in type handling between SQL and your language of choice make ORMs a virtual minefield. Some have even said that ORMs are the Vietnam of computer science.

Really, though, it seems rather silly when you think about it. Why go to so very much trouble to map the data from an OO format and back again? Why not just keep the objects in object format all the time?

It’s been done. But it doesn’t work terribly well, and certainly doesn’t have anywhere near the robustness necessary for large and long-lifetime applications. Why not?

As it turns out, the limitations of a relational database are the very thing that make it so robust over the long term. There’s benefit to be gained by forcing the data to be turned into a simple, transparent, structured format every time you save it. Or indeed, to force an explicit saving step at all, instead of just persisting objects flagged to do so.

ZODB and its ilk are hauntingly similar to a core dump: easy to save and load, but fragile over any significant timespan. There’s no enforced strictness to data cleanliness when you can just dump everything out effortlessly.

Another case of embracing constraints? Maybe. I’d like to think that someday this longstanding dilemma will be resolved. Until then, thinking about ORMs this way will make me feel better about using them.