Live data from Hacker News

Never use a dependency that you could replace with an afternoon of programming

blog.carlmjohnson.net

91–100 of 333 posts

Re: Never use a dependency that you could replace with an afternoon of programming

#91
post #69

It's a matter of judgement, but here's a few observations: - With a little experience, you know what gets fiddly and what doesn't. Today for instance, I needed a way to remove tags in an SVG document, which looks a lot like HTML tags. I quickly ended up finding that Regex is not the solution (a well known guy on SO wrote an answer that looks like a huge warning sign). I also couldn't enumerate all the corner cases. S…

> a well known guy on SO wrote an answer that looks like a huge warning sign For those who are in today's 10000, you might mean this piece of art: https://stackoverflow.com/questions/1732348/regex-match-open...

Or...

https://blog.codinghorror.com/regular-expressions-now-you-ha...

Re: Never use a dependency that you could replace with an afternoon of programming

#92

Probably good advice, but when was the last time a programmer accurately scoped a problem when they said it will take “an afternoon” to build?

> Probably good advice, but when was the last time a programmer accurately scoped a problem when they said it will take “an afternoon” to build?

This is why you time box things. Spend XX hours trying to get a thing working and if you aren't close, you grab a library and move on.

Re: Never use a dependency that you could replace with an afternoon of programming

#93

A hundred afternoons later my small application is finally completed; now I must maintain update and document it all for ever rather than relying on third party components. What I really wish is people would look closer to home; for example use some of the thousands of functions that ship with your operating system before downloading a package.

I have this problem at work with our node apps.

With things like reduce, map, the like their is less need to rely on lodash or underscore for them.

Re: Never use a dependency that you could replace with an afternoon of programming

#94

Earlier quoted context omitted.

This is actually a great example of why you SHOULDN'T use left pad. I've not profiled it, but I'm going to guess that now-a-days this will be faster than the current implementation on npm. function leftPad (str, len, ch) { str += ''; len = len - str.length; if (len Why? because the VM is (very likely) going to do exactly what the cache would have done. It can replace `ch.repeat(len) + str;` with a presized string all…

What magic would enable that? I don't think the VM is likely to cache a string of 6 spaces, it has no way of knowing that would be a common parameter, and no heuristic to determine that it's likely. It may specialize or inline, but that's a separate matter. P.S. I think there's a bug here.

JIT is the magic sauce and this a pretty regular optimization.

    Step 1, inline repeat.
    Step 2, remove the intermediate array allocation
    Step 3, allocated a string array sized for the pad + str
    Step 4, Use one of the many CPU instructions to repeatably copy the padding character and then the `str` into the same array of characters.
None of these optimization would be out of the question for the Jit (and I'd expect them). You don't need the cache at all, it's just a waste. The only thing it saves it creating the intermediate string which is HIGHLY likely to be optimized away with the simple code.

Re: Never use a dependency that you could replace with an afternoon of programming

#95
I've always called this the "guy in the basement" effect.

In the beginning, the guy in the basement would have an awesome idea for a library. He would spend 27 hours a designing it, coding it, testing it, and making it awesome.

The "guy in the basement" moves out because his partner wants to spend time with him. They start to live lives outside of the world of maintaining open source libraries. The partner asks, "Are you getting paid for all of this?" and the guy says, "No. It's open source. It's a good thing." but in saying it out loud to his partner, his priorities shift.

Over the next year, the library deteriorates. It gets forked, other people ask to maintain it, he relents, but no single person has the vision. The library becomes a mish mash of priorities and no longer has the awesome cohesion it once had.

Everyone using the library is very sad. Some are angry. An awesome replacement appears from another guy in the basement.

The cycle repeats.

Re: Never use a dependency that you could replace with an afternoon of programming

#96
I'm sure I could write a basic HTTP client implementation for the current needs of my project in an afternoon. That doesn't mean that I shouldn't be using libcurl or whatever instead, though.

It's perfectly reasonable to conclude "my need is a subset of a larger but well-defined task for which there's a bunch of mature, proven and widely available libraries – I should leverage them".

Re: Never use a dependency that you could replace with an afternoon of programming

#97
A huge benefit of using dependencies in your codebase is that other members of your team (including future members) have a good chance of already knowing how the dependency works, and how to use it.

If I rewrite package Foob because it only takes me 3 hours to write (let's call it Boof), and my colleague Mary on another team also does so, then the chances that our needs, specific implementations & usage patterns are the same, is pretty low. When I transfer to her team six months from now, I have "my" code that I know how it works, and I also have "her" code that I don't yet understand. I've got to relearn the new interface.

Or, if we see this as opportunity to unify our needs across codebases/teams, one of our libraries get the features of the other bolted on. In this way, we're just spending our combined time building a less-good Foob, instead of actually doing something useful.

But instead, if Mary says that Foob is high-quality because she looked at the code, checked the community, etc, then I can just trust her judgment. Foob already has most the features that I thought I ain't gonna need. I can re-use Foob in multiple projects, and the documentation for Foob is certainly better than what I would have written in an afternoon, so future team-members will also pick up Foob faster than my Boofy custom implementation.

Re: Never use a dependency that you could replace with an afternoon of programming

#98
I think the mistake described in this blog post needs a name. Let's call it premature dependence.

Like premature optimization, premature dependence compounds your maintenance burden over time because you predicted a problem which, if you had waited for evidence, would never have materialized.

In premature optimization, you imagine that a simple solution won't perform adequately, so you invest in building a more sophisticated solution up front. In premature dependence, you imagine that a simple implementation won't adequately address your needs, so you bring in a feature-rich dependency right away.

Both are driven by the fact that we spend the vast majority of our time, effort, and emotional energy dealing with rare cases. You don't spend hour after hour, day after day, meeting after stressful meeting talking about the database that scaled fine or the code you wrote once at the beginning of the project and never touched again. If you don't account for how the successful stuff disappears into the background, your model of reality will be skewed by rare traumatic events. (Which is kind of the point, evolutionarily speaking, since it serves as a kind of crude risk analysis, but it's not hard to do risk analysis better than your amygdala does.)

Of course, applying the rule in practice requires judgment. Some problems are inherently difficult; some explosions in complexity are predictable; you don't have to pay long-term costs on POCs and failed experiments; if you say you support ISO-XXXX format then you had better support every obscure corner case; etc. But it's good to keep in mind that the long-term cost of an extra dependency can be greater than the long-term cost of a few hundred lines of unchanging, unit-tested code.

Re: Never use a dependency that you could replace with an afternoon of programming

#99

Avoiding dependencies is a noble goal, and something to be valued, but this simple rule is too simplistic. The problem lies in the fact that there are a great many things I can hack together in an afternoon to "replace" some kind of external dependency, but the quality discrepancy of these hacks is highly variant. My understanding of what can or should be done in an afternoon might differ with my colleagues'. Unfortu…

A simple example would be an HTTP client. It’s easy to write a naive thing that makes GET requests with no request body, TLS, connection pooling, etc. Why should I use a dependency when I can write it in an afternoon? Well, I used to think that before I tried writing one :) The first draft was easy. Adding features got messy.

Re: Never use a dependency that you could replace with an afternoon of programming

#100
post #63

No. Some reasons: 1) As everyone else has said, we are horrible at estimating. 2) We think we might only need 1% of an external dependency, until we do not. Case in point: By this criteria, no one needs a grid/datatable library.So we write it "in an afternoon". Then we're asked for an export to Excel. Later on we're asked for pagination with large data sets. And then an export to PDF. How many afternoons did that cos…

> We think we might only need 1% of an external dependency

I've seen the opposite just as often. Someone things an external dependency can just plug in and solve the problem, then 16 hours later they've made the basic thing work with an external dependency with a bunch of internal code on top of it. Now you have a pile of fragile code which breaks when the dependency changes underneath you, you have a bunch of in-house code supporting a thing which might not be getting up-line support anymore, and you still have a bunch of internal code to maintain.

> Case in point: By this criteria, no one needs a grid/datatable library.So we write it "in an afternoon". Then we're asked for an export to Excel. Later on we're asked for pagination with large data sets. And then an export to PDF. How many afternoons did that cost you?

You can always migrate to a library at a later date if the scope changes. More-so, you don't know how the scope is going to change, how do you pick a dependency based on future scope changes?

Post reply on HN