[ art / civ / cult / cyb / diy / drg / feels / layer / lit / λ / q / r / sci / sec / tech / w / zzz ] archive provided by lainchan.jp

lainchan archive - /λ/ - 17686

File: 1470004377488.png (72.3 KB, 300x300, __tobiichi_origami_date_a_live_and_pixiv_drawn_by_mugen_ouka__b468b755e5d0e3c32f7908cfb3db29ed.png)


When writing software, there is always a trade-off to be made between a solution that does just what you want now, and a more general solution that might be useful in the future. This is typically resolved by invoking YAGNI: You Aren't Gonna Need It. Although sometimes You ARE Gonna Need It and picking the special-case solution will come back to bite you. One of the hallmarks of a great programmer is being able to recognised when the increased up-front complexity of the general solution will pay off in the long run.

We take a different attitude when introducing external dependencies. It seems that we're much more tolerant of pulling in an external dependency which does a lot more than we need. This is usual justified by pointing out the advantage of not needing to develop, test, and maintain some code in house. The typical invocation here is Don't Reinvent The Wheel.

But where is the line? At what point does the more general external solution become so complex that apparently duplicating the necessary functionality internally is a better idea?

I have been thinking about this recently, due to some difficulties we have been having with a couple of libraries at work. Each implements some behaviour we need, and each has its own performance failings. This weekend I decided to experiment by implementing JUST what we needed and nothing more, and by restricting myself like that I could take advantage of the specific use-case and produce a library which is much more performant.


If I'm writing in a high level language, such as Lisp, I tend to abstract, as that's what expected when the language and environment are so closely connected.

I take a very different view with Forth and machine code programs. Everything you don't use is cruft. If you only use a mathematical routine on even numbers, it only needs to work with even numbers, even moreso if this increases efficiency.

Unfortunately, we live in a world where many programs are expected to perform increasingly complicated actions requiring complicated means of communications. Imagine needing to operate with a JSON API to make lights flash, as an example.

Regardless, there's still very much a place for software that only does exactly what it's supposed to. Writing both types of software is very fun, but I get a feeling of satisfaction from writing the ever smaller and more compact programs doing only what they should that I don't from the general purpose ones.


There is definitely a feeling of satisfaction in solving a task efficiently and precisely.

The particular thing I was working on was a database to store log-structured data. The two libraries I mentioned each use a generic key-value store as the backing storage. By restricting myself to log-structured data, I was able to get an order of magnitude performance improvement on push/pop operations, even though the two key-value stores are regarded as high-performance in their own right.


If you know what the program is supposed to do before you start writing it, then it's much easier to see how general it should be. If pulling in a library adds more complexity than a home grown solution, then don't do it.


Platform is a great influence on this.

If only using a single platform, I'd recommend truly taking advantage of it unless there's a very good reason not to. For something like video games, this is sometimes necessary for performance requirements and whatnot.



It's about features, not quality. If you can implement a feature by adding a dependency and it's good enough, do it, it should be fine in 80% of cases. If quality of implementation causes you trouble, write your own solution, new libraries with various properties emerge from time to time. Reinvention of the Wheel is about the case when you write your solution without justification and get an average result that could be satisfied by an existing solution.


I personally have a bit of a problem with the "don't reinvent the wheel" approach.
It makes sense, but it feels awful when software ends up having a soykafload of dependencies, often depending on specific versions of a library, or bloated libraries filled with vulnerabilities waiting to jump out.
I know... "static linking", which is kind of a solution for half of the ugliness inherent to libraries, but I still shy away from programs that instead of taking the KISS way, instead go and link up dozens of libraries.


I think this is only a problem if they rely on libraries that have a lot of functionality than are used in the library.



I think minimizing dependencies is often a good exercise unless you're using an incredibly trusted library - libev or protobuf for instance. But in the more general

>go with something that works now vs optimal behemoth

Upgrading the old working software with more experience and bug knowledge is just easier and makes you look like a badass at work. So don't reinvent the wheel on your first try, but down the road you can find some pretty neat solutions.


Or a lot of libraries, it feels really messy when a project has a bunch of dependencies.
Dependencies themselves are usually a problem which sometimes arise from behind the useful work of package managers, but also make the program deviate from standards more and more and it makes it less simple as well, as >>20597 points out, it's a soykaffest of features most of the times.
Other times it's that the libraries themselves are some sort of behemoth, for example webkitgtk.
Vim+lua+python+ruby is another example of library blowup, thankfully they are optional.
It's not that I'm against libraries. If a project uses curses, or SDL, or even gtk (a GUI library, I don't like GUIs), I don't care, they are standard enough. But sometimes I get a bunch of dependencies for really obscure libraries which I never know what they do, and those libraries are only required by this one program, and it means only work (I have to get out of my way) to find out what they do and if they don't have some nasty vulnerability that the developers (it being a rather obscure library) haven't fixed.
Nope, I don't feel at all comfortable around library abuse.