Tools are(n’t) the Problem
The other day I was looking at Twitter and came across this status from @marcoarment.
Q: How do I perform this simple task in Javascript?
A: Just include BloatJS and then call this function. [ACCEPTED]
http://t.co/o1WqnlGHUY
— Marco Arment (@marcoarment) May 16, 2015
I can definitely agree with the sentiment of the tweet. In his post he references an article by Peter-Paul Koch claiming that tools “have become the problem” (emphasis in the original).
Marco goes on:
The entire culture dominant among web developers today is bizarrely framework-heavy, with seemingly no thought given to minimizing dependencies and page weight. Most times I land on a Stack Overflow page with a simple Javascript question, the highest-voted answer is “Just include [framework X] and then call this function,” even though a few posts beneath it is a perfectly suitable, standalone 10-line function.
This resonates with my own experience with Stack Overflow over the past few years and with doing Internet research in general seeking to answer any basic web development problem.
I’d like to cite some examples of this, but I can’t recall any right now. Send them to me if you run across any.
That said, something in me bristles when I read the last line in Marco’s post: “even though a few posts beneath it is a perfectly suitable, standalone 10-line function.” Sure enough I know what he’s talking about. But almost every time I tried to rely on one of those “perfectly suitable, standalone 10-line” functions I’ve discovered that it wasn’t perfectly suitable after all because it didn’t handle some edge case. (Think about anything having to do with DOM element dimensions or handling Date/Time in Javascript.) I’d much prefer to use a library containing an implementation that was carefully written, unit tested, and then battle tested by virtue of being part of a framework that gets used by hundreds if not thousands of sites every day.
This issue becomes particularly significant where cross-browser compatibility comes into play. With mobile browsers implementing features in all manner of different ways, cross-browser compatibility is worse now than when all we had to worry about was whether or not a site worked in IE6, Firefox, and maybe Opera. With mobile, even using frameworks is not a sure thing.
There are reasons why all these tools exist today: rather than each web-developer trying to solve a problem badly, we decided to write frameworks that solved the problem well for a targeted set of common browsers. This led to things like Prototype, MooTools, jQuery, the YUI framework.
Just look at PPK’s event compatibility tables to see why JavaScript frameworks exist to begin with. Let’s not even talk about the crap DOM API. Without jQuery, coding even the simplest interactive UI would require hundreds of lines of verbose code. The only way to avoid this verbosity is to write a set of commonly used functions that wrap up the DOM, et voilà! You get jQuery or Prototype or … what have you.
Want to get the dimensions of a particular element in the DOM or the dimensions of the document? Sure you could just roll your own that will work 90% of the time until the next browser update decides to break it and you or the next programmer to pick up your project has to go spelunking into your code to see what’s wrong, or just use jQuery and when that fateful update comes you or the next programmer can just upgrade jQuery and chances are the problem will go away without wasting time debugging. Problem solved.
Except, things aren’t that simple. Every programmer has his or her idea about the Best™ way of solving a problem. This leads to an overabundance of tools that solve similar problems in subtly different ways. Each tool, having a different developer behind it, will have different level of quality and different frequency of updates, or it might just stop getting maintained completely. Each tool will have completely different conceptual models and APIs so they’ll be incompatible. Replacing tool X that performs function Foo with tool Y that also does Foo won’t be just a matter of dropping Y in place of X, but a laborious process of testing and debugging.
This is where the concept of programming to an interface, not an implementation brings a ray of hope in an otherwise hopeless situation. If everyone writing a tool to perform function Foo would just agree that we’ll all use the interface IFoo then replacing X with Y would be trivial. The problem is, no one can even agree on what IFoo should look like.