Sunday, January 20, 2008

Dependency Hell

A software dependency isn't like a drug dependency -- it doesn't mean you can't survive without a software fix. It can actually be a lot worse. A software dependency is when one program -- the one you need -- depends on another program -- one you probably don't know exists.

Dependency Distress
You load the software you need, but it doesn't work. Turns out it can't work without help from some other program. Worst case? It takes you forever and a day to figure out what elusive bit of code your program needs to operate, then you start the process of finding and installing it. Then you find out that the code on which the program you need depended on has a dependency of its own.

And somewhere along the line you discover that one of these "dependencies" is actually a specific version of some obscure bit of code, not the one you found.

This is called dependency hell. And that's a complement to the devil. Like most circles of software hell, this one started out as a way of making things easier.

Any substantial program is made up of a bunch if different processes. Some of those processes are used over and over in lots of different programs. It doesn't make sense to rewrite those common processes for every new program, instead programmers just drop in a link to an existing bit of code. These frequently-used bits of code, when they're organized into a group, are commonly called libraries.

DLL Hell®
Microsoft tried to fight its way out of dependency hell by creating a system called DLL, for dynamic link libraries. With DLLs, Microsoft was able to escape the dependency circle of software hell and -- this is innovative -- create a new circle called "DLL Hell." I capitalized it because I like to think of it as proprietary: Microsoft invented this particular circle and, as far as I know, owns the rights to it.

In short, DLL became a Hell because the little bits of code in the library could change without changing the overall library. Why's that bad? You install some new software, it replaces the old DLL with a newer, slightly changed, DLL and gets to work. That's fine, for a while.

When you try to use some other program, it calls on the DLL it's always relied on, finds that the bit of code it needs has changed, and returns an error message: something about not being able to find a required DLL file. After much anguish, you reinstall the program and replace the newer DLL with the older one. Now your old program works fine but ....

Yeah, that's why they call it hell. Makes rolling a rock up a hill forever seem almost pleasant.

Cycles, Chains, Trees and other Metaphors of Dependency
Once you're in a circle of hell, you find it has its own subdivisions. Dependency hell is no different. Some dependencies are circular and continue along a curve until they wind up trying to reuse a bit of code that's busy because they're already using it. The problem is as awkward as that sentence describing it.

Some dependencies seem to trace backward along a line that ultimately leads to a guy sitting on a rock with an abacus -- or maybe even an inchoate idea of what an abacus could be.

Some dependencies branch off endlessly as if Escher had designed a tree.

For those of us who aren't archaeologists or theologians of software hell, the result is fairly consistent: our computer won't work and we're late with the report/tax return/homework/online reservation and it's going to ruin our career/life/chance of getting into Harvard/date.

Moving toward Stasis
One way to avoid dependency hell is an increasingly-affordable form of purgatory. Think back to DLL Hell. The problem there is the first "D." It stands for "dynamic" and it means that the library can change independently of the software that uses it. That's efficient because you don't constantly have to change one (library or software) every time you change the other, and because you don't have to repeat all of those reusable bits of code. It's inefficient because it doesn't work, for the reasons stated above.

The solution? SLL, for static linked library. I don't think it's really called that, but it describes the solution reasonably well. You install a library of commonly-used code and a bunch of programs link to it -- but statically. The library doesn't go away as long as any other software is using it, and the software never links to a different library.

That avoids all the cost of linking to changed libraries that won't work with various versions of software. It comes at the cost of having to keep additional libraries on your computer. But hard drives are getting bigger and cheaper at the same time and it's a small price to pay for a way out of hell.

sudo apt-get God
I'd like to tell you that's Latin for "God helps those who are just trying to finish a report/tax return/homework/online reservation so they can have a decent career/life (outside of prison)/chance of getting into Harvard/date." But it's not.

In fact, it's not even Latin. Or English, as far as i can tell. It's the way some versions of Linux try (pretty successfully) to keep us out of dependency hell.

It started with Debian, an early easy-to-use version of Linux that has branched off into, among other 'distros" Ubuntu, the Linux I use. From a user's point of view, it starts with a program called apt-get.

To install a program in Ubuntu, you type into the terminal: sudo apt-get install [name of the program]. The "sudo" part gets you permission to make changes to the operating system; "apt-get install" instructs your computer to get the program and its dependencies and install them; "name of the program" says what to get and install.

The key to making this all work dependency-wise is something that's slightly behind the scenes. Before you can use apt-get, you have to tell it, in a general sense, where to get it. The where, in this case, is a place called a repository.