Live data from Hacker News

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

blog.carlmjohnson.net

171–180 of 333 posts

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

#171
post #74

This sounds like pre-mature optimization. If the library does what you need it to do, use it. If it becomes a problem later, then optimize it. That last thing you want to do is spend a bunch of time reimplementing code when: 1) It may not matter at all, 2) You might miss important edge cases, or 3) You got everything right but you still have to maintain it forever. If it's going to take you three days to integrate th…

I remember starting with an overloaded library from NPM where I used some basic functionality. That worked fine for a while. When later I got lost fixing a defect in the tangle, I just ripped out the parts I needed and made a trimmed version. The interface remained the same, for the parts I was using. Nothing to adapt.

In this way I had little investment in the beginning. And once I knew what I needed, it was another small investment to clean the code.

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

#172

Earlier quoted context omitted.

Yeah benchmarks can be much more difficult to get right than it might seem at first glance. Good thing they didn't try to write their own benchmarking code, otherwise they might have fallen into those traps you just mentioned. Luckily, they didn't, and instead pulled in the the `benchmark` library as a development dependency. The author of said library works on V8, and already considered all those problems and much,…

You are making the assumption that the library doesn't have the flaws I mentioned. It does (You can go read the source yourself https://raw.githubusercontent.com/bestiejs/benchmark.js/2.1.... ) There's no portion of the code that does warmups. There's no portion of code that "blackholes" the results to keep the JIT from optimizing away the code under benchmark. There is a lot of code though... so that's... good? You…

Okay, you win. I'm not going to read the entire source of that package just to make a point. Though I do find it strange that the author of that library would write an entire blog post on the topic and then not take his own advice in the implementation of the library he wrote.

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

#173

Earlier quoted context omitted.

Yeah benchmarks can be much more difficult to get right than it might seem at first glance. Good thing they didn't try to write their own benchmarking code, otherwise they might have fallen into those traps you just mentioned. Luckily, they didn't, and instead pulled in the the `benchmark` library as a development dependency[1]. The author of said library works on V8, and already considered all those problems and muc…

I know, I read the benchmark suite code. The benchmark suite itself isn't doing the things I said it isn't doing. Sure, It's popular. It's also wrong.

Okay, you win. I'm not going to read the entire source of that package just to make a point. Though I do find it strange that the author of that library would write an entire blog post on the topic and then not take his own advice in the implementation of the library he wrote.

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

#174

Earlier quoted context omitted.

"smaller" there was short-hand for "more focused, purpose-built to your problem, less generic". All of those properties make the code easier to reason about and test. Being easier to reason about, and being a more exact abstraction for my needs, are both incredibly valuable properties.

More generic is better. If I go into a codebase that uses standard libraries. Even if I don’t know how to do something about it someone on the Internet does. Your custom framework - not so much. I don’t have to care about how the underlying libraries work. I can treat them as a black box.

What do you do when the black box doesn't work?

Almost everything I work with has bugs, so chances are I'm going to run into one. It's a lot easier for me to fix bugs when there are fewer layers and more of them are written by me. Of course, I can't write all the layers, but if they run on my service, I have to be prepared to fix them, or suffer from them being broken until a benevolent force fixes them for me. (Sometimes that happens, but usually not for the harder problems)

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

#175
post #157

Earlier quoted context omitted.

They failed at writing a correct O(n) left pad in their benchmark: https://github.com/left-pad/left-pad/blob/master/perf/O(n).j... They are repeatedly appending a single character to the front of a string. This is actually O(n^2) so of course they are winning against it.

That would depend on the underlying implementation of the string object, no? (If the string is implemented as a linked list it's O(n)) Anyway, it makes no practical difference in this case, since the one they labeled "O(n)" is the naive implementation that most people would write if they implemented left-pad themselves.

I highly doubt js engines would compile a string down to a linked list. But you're right they might compile it to a circular buffer or deque which can have O(1) prepends.

Quick googling shows that this optimization might exist but only for firefox and only if you use "unshift": https://lannonbr.com/blog/2020-01-27-shift-optimizations https://jandemooij.nl/blog/2017/12/06/some-spidermonkey-opti...

But it's very unlikely that the jit can optimize `str = ch + str;`

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

#176
This is interesting, because I had this issue. In one java lib I wrote, I needed to build an URL, so I naively pulled apache http common URL builder, got it done in one line, and went on.

But a few time later, I realized (well someone reported an issue) that depending on the android version, it would break. My first reflex was to try to bundle just what I wanted using some graddle class renaming plugin, it was a nightmare.

Then I just realized how stupid and lazy I had become, being able to just pull dependency for anything made me forgot I could just write the code.

In the end I dropped the dependency and wrote what I needed myself.

If you are interested, commit here: https://github.com/kuon/java-phoenix-channel/commit/2a3a976d...

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

#177
post #107

My rule is, don't use a dependency to implement your core business. Is JSON parsing our core business? No, so why would we ever write -- and thereby commit to supporting for its entire lifetime -- JSON parsing code? All the code you write and support should be directly tied to what you as a business decide are your fundamental value propositions. Everything else you write is just fat waiting to be cut by someone who…

> don't use a dependency to implement your core business In logic language, you're saying "If X is your core business, don't outsource X". > Is JSON parsing our core business? No, so why would we ever write -- and thereby commit to supporting for its entire lifetime -- JSON parsing code? All the code you write and support should be directly tied to what you as a business decide are your fundamental value propositions…

I think the problem is that the individual contributor has decided to make that chunk of logic their business. This will probably not benefit the team or the organization.

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

#178

The single best way to avoid dependencies is to use a language with a large standard library. Given the variance in standard library coverage, it’s rarely productive to argue about this topic in a language agnostic way. Using only stdlib in Go is very different from using only stdlib in JavaScript.

i'm so used to python's stdlib that whenever i go to javascript i get legit angry. i really like writing typescript code, but holy shit, when you have to pull libraries to even the smallest thing (lol left-pad), it get super infuriating.

JavaScript standard library was maybe bad in the past but nowadays they added a lot of features (yes, even left-pad).

Sure, if you know that you have to support old and broken browsers you have to use these dependencies to ensure correct support, but if you know that your code will run on a specific interpreter (for example a modern version of nodejs, or modern browsers) you don't have to worry about it too much.

Also most JavaScript programmers tends to abuse dependencies, I mean even for things that are really 10 lines of code that you write in 1 minute.

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

#179

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.

I had the opposite experience. All I needed was a way to do a simple GET. That's it (and that's all it still is, by the way). Instead of spending half an hour writing the code, I decided to use libcurl---that's what it's for, right?

Until I found it wasn't installed on some of our test machines (it was needed for testing, not for production and for reasons beyond my pay grade, libcurl was not available on the machines). Then I thought, well, I could include the libcurl into our vendor repo. It worked, but it was a nightmare to use. It took way too long to figure out the proper "configure" options to use for what systems, it nearly tripled the time to build it on the build servers, and even then, it was hit-or-miss.

After several years of this misery, I removed libcurl, and wrote what I should have years earlier. Using libcurl as a dependency did NOT save us any time.

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

#180

Earlier quoted context omitted.

You are making the assumption that the library doesn't have the flaws I mentioned. It does (You can go read the source yourself https://raw.githubusercontent.com/bestiejs/benchmark.js/2.1.... ) There's no portion of the code that does warmups. There's no portion of code that "blackholes" the results to keep the JIT from optimizing away the code under benchmark. There is a lot of code though... so that's... good? You…

Okay, you win. I'm not going to read the entire source of that package just to make a point. Though I do find it strange that the author of that library would write an entire blog post on the topic and then not take his own advice in the implementation of the library he wrote.

Tell me, where in that blog post does he mention doing warm up cycles or avoiding having the JIT optimize away the method? (Hint, he doesn't mention that... so, no, he didn't actually miss his own advice.)

The article is completely consumed with getting the timing of benchmarking right. Which, to be fair, is a place where microbenchmarks often go wrong. It, however, isn't the ONLY place they go wrong.

Post reply on HN