Applications and libraries


In a recent discussion around one of Steve Yegge’s blog post, an incidental remark was that it’s OK that a language makes it harder for a library creator than for an application developer. This point was made by David Pollak and Martin Odersky in relation to some of the complications that you need to handle when creating a Scala library that you can intuitively use without a full understanding of the Scala type system. Make no mistake, I have lots of respect for both Martin and David, it’s just that in this case I think it’s actually a quite damaging assumption to make. And they are not the only ones who reason like that either. Joshua Bloch’s book Effective Java includes this assumption too, in many places.

So what’s wrong with it then? Isn’t there a difference between developing an application and a library. Yes, there is a difference, but it’s definitely not as large as people make it out to be. And even more importantly: it _shouldn’t_ be that much of a difference. The argument from David was that when creating a library in Scala, he needs to focus and work with quite complicated parts of the type system so that the consumer gets a nice API to use the library through. This process is much harder than just using the library would be.

Effective Java contains much good advice, but most of them are from the perspective of someone who creates libraries for a living, and there are a few places where Josh explicitly says that his advice isn’t necessarily applicable when writing an application, since he doesn’t have that point of view.

Let’s take a look at a fundamental question then. What is actually a library, and what is an application? In my opinion, a library is a module providing functionality of some kind, restricted to a specific domain. This can be a horizontal or vertical domain, that doesn’t matter, but it’s usually something that is usable in more than one circumstance. It’s not uncommon that libraries use other libraries to implements its functionality. An application is usually a collection of libraries that provide functionality to an end user. That end user can be either a person, a program or another computer – that doesn’t matter. But wait, isn’t libraries usually also created to provide functionality to other pieces of code? And even though libraries have a tendency to contain more specific code, and less usage of other libraries, the line is extremely fuzzy.

The way most applications seems to be built now, most of the work is done to collect libraries, provide the missing functionality and glue them together in some way. But that doesn’t mean that the code you write in the application won’t be used as a library by another consumer. In fact, it’s more and more common to try to reuse as much as possible, and especially when you extend an existing application, it’s extremely important that you can consume the existing functionality in a sane way.

So why make the distinction? Doing that seems to me to be an excuse for writing bad code if it’s in an application. Why won’t we as programmers admit that we don’t know if someone else will need to consume the code later, and write the best code we can, including creating usable ad well thought out public APIs? Yes, the cost and time will be higher, but that’s true for writing tests too. I don’t see any value in arguing that libraries should be designed with more care than application code. In fact, I think that attitude is actively detrimental to the industry. And adding a language feature to a language that is complicated, and then arguing that only “library developers” will need to understand it is definitely not the right way to go. A responsible developer using a language needs to understand how that language works. Otherwise that developer will sooner or later cause a great mess. It’s just a matter of time.