We haven’t forgotten how to program, we’re making the best of what we have
After NPM’s left-pad debacle earlier this week, David Haney, my coworker and a gentleman and a scholar by all accounts, wonders if we’ve forgotten how to program.
I don’t think we have — I think we’re actually doing pretty good given the situation.
First, a bar chart
There are a lot of good standard solutions out there for common problems, but there are still a few gaps left over too.
Plz send me teh codez
- Write your own function from scratch
- Take a dependency on a library that contains the function
- Copy and paste someone else’s implementation into your project
All of these are perfectly valid options, and they each have their own strengths and weaknesses. Padding a string seems like a pretty straightforward task, so writing your own implementation wouldn’t be outside the realm of reason… but you give up any opportunities for support from the community, short of replacing the function later on and potentially having to refactor your code to match the API of the replacement. Depending upon an external library gives you the chance of updates and community contributions without much effort, but it exposes a point of failure if the dependency (or the infrastructure it’s hosted on) goes away or changes its API. Copying and pasting works too, but now you have to grok someone else’s code and you have to deal with changes by hand if the code needs to be changed or improved.
Which one’s the right answer? Well, it probably depends on the complexity of the function you need to use. For something like padding a string, it’s such a simple problem that rolling your own is the obvious answer.
Yeah, you read that right. What’s being described as an unnecessary library for a simple function had three released revisions (and a fourth that didn’t make its way to NPM) before the package was unpublished. Was it because the function’s author was a bad programmer? I’d argue not — the progression of the code looks pretty similar to how any developer would revise such a function after they started testing and using it.
I’d also argue that the author’s implementation is still incomplete. What happens when you pass in a padding character string with multiple characters? Does it align the string to the left or the right? What about a source string with multibyte Unicode characters? What about a multibyte Unicode character for padding? What happens if you pass an object as the padding character? (I leave these questions as exercises to the reader.)
As it turns out, string manipulation actually isn’t always easy. The left-pad library has four test cases, which are hardly exhaustive in comparison to wide gamut of arguments the function could be expected to handle. I’d also wager that most developers’ self-written padding methods don’t have any tests, and probably don’t have good answers to the open questions above.
It’s easy to claim that a problem is simple at first glance, but it’s ignorant at best (and arrogant at worst) to claim a quick solution as the “obviously right” answer to a problem that gets more complex as you peel back the layers. There’s currently a TC39 candidate proposal for adding string padding to the ES7 specification. It’s been under development since July 29th 2015, and it has 65 commits by five contributors. You can read the source for the proposed polyfill; it’s more complex than left-pad, and it’s probably more complex than most one-off pad methods.
We as developers depend upon proven-correct (or at least proven-mostly-correct) functions provided by runtimes, standard libraries, and very common external libraries that receive community scrutiny and updates. Choosing to depend upon someone else’s code for common tasks shouldn’t be mocked as passing the buck, it should be the default — how many hours do you think have been spent by developers reinventing and debugging string padding methods in their applications? Don’t get me wrong, every developer should certainly be able to write a baseline string padding function… but that doesn’t mean any of them should have to do it to make a production application on a popular platform work.
The moral of the story
Maybe some of today’s Node applications and libraries are made of mishmashes of dependencies… but what’s the alternative that’s available to people who are just trying to get stuff done? Libraries like jQuery and lodash do a great job of providing developers with useful utilities, but they’ll never be exhaustive — there will always be something common that someone needs, and they’ll always face the aforementioned options with their associated benefits and risks.
This shouldn’t become an excuse to write off small libraries as unnecessary (because even the isarray package has utility), it should become a reason for more developers to learn about the tradeoffs that surround taking dependencies so they can make better-informed choices in the future. We should probably all be thinking more critically about what goes into our applications and listening less to the cargo cult about things that are “automatically” better or worse.