> 1. Your handrolled solution is likely worse than the library anyway
I quite doubt that, though I used to feel the same.
The one feature I need in the library is probably implemented for a specific use case which is undocumented or misrepresented; and use cases outside of that are likely to be egregiously unsupported. Fixing the issues is almost always more work than just implementing X directly and looking up gotchas.
(aside: to understand this first-hand, go pick any JavaScript[0] animation library, and then go add a library that integrates it the core framework you're using (or not)... et voila, enjoy the descent into hell.)
A simple implementation of X that doesn't lock you into patterns you don't need or will one day harm you is worth its wait in gold. Seriously, I'd rather sacrifice DRY code than fuck myself eight months down the road by using a shitty over-engineered pattern that doesn't actually fit my needs.
> 2. You're wasting effort reinventing the wheel
Probably not; it turns out most of the wheel was invented and given to you in the language and runtime. For the article, it's 100% true, BEAM is pretty much an operating system and a great one at that.
We often abstract for the sake of abstraction; I honestly think Elixir/Erlang has helped break me of quite a bit of that. Rust is also nice because it'll make things so very painful for you when you abstract for no reason.
> 3. You risk adding unnecessary opacity by littering the program with dense math
Opaque libraries are the exact same thing but are even harder to understand since the source code doesn't comply with your same coding standards, methodologies, or test suite.
> 4. Other programmers will assume there is a pertinent reason you hand-rolled the algorithm instead of using the library. Now everytime someone touches that code they have to reverse engineer your approach to see what it does different from the library such that you had to roll it yourself (surprise: nothing!).
Documentation is the answer here, it doesn't have much to do with library or DIY.
Why go through the trouble to properly evaluate a solution, decide the best solution was to implement your specific use case (or otherwise), and then not document it? You're just asking to repeat yourself or forget.
On the flip-side, its really easy to assume that library authors did something brilliant when in fact they've done the opposite. Or someone will assume you've chosen this library because you took the time to properly evaluate it and never question it...
Ex.
After eight months of having the library run slow and leak memory some junior engineer pulls you aside and softly says "I have a minor in mathematics, I noticed that library Y is only doing simple matrix multiplication... I can do the same thing with this [shows you four lines of code] and its a lot faster... I just assumed we had to use that library since its in our code base."
Adding libraries before you need them causes more headaches than not because now you've littered a dependency throughout your code which may not be sufficient for future use cases. This goes back to I'd rather have less DRY code than be bound to a shitty inflexible pattern.
> The two exceptions I imagine are 1) if you really do absolutely need some slightly modified microoptimization of what the library does or 2) if you are working for a platform where there is good reason to avoid even slight bloat (embedded).
I don't totally agree with either of those statements fully but I don't strongly disagree with them either. I'd like to add for me these would be of much high significance:
1. Your future use case are unknown.
2. You do not know if the library will be maintained; so, by using it, you're going to own it anyway. There are no free lunches.
3. You're using only a small, defined subset of some standard (i.e. RFC or specification). The existing solutions provide too much cruft for your specific use case.
4. The solution is obvious and has one correct answer. In some languages this is easier because of strong conventions and standard libraries. In others, this is probably a pipe dream.
5. The libraries are not tested adequately or are not easily testable.
I dunno, over the past few years especially, I've just started doing more things myself and yeah things do take slightly longer to start (sometimes...) they almost never take more time to maintain, expand on, or use.
Each line of code used by your project is a liability (debt), not an asset, on your balance sheet... Less code, less liability, less debt.
[0] No offense to JavaScript <3, I only choose it, because it's so ubiquitous.