Comment by sneak

5 years ago

I used to have this approach, but when you start to take deps into account, it is often preferable to have a medium amount of code in your own codebase (that eliminates some bulky deps) to a small, fast, clean/easy to read in full codebase that depends on some large external libraries that bloat the overall size of "lines of code in use in this application".

Now I am a dependency minimalist (as much as is practical, it's a continuous gradient trade-off and naturally YMMV) more than I am a pure code-written-here minimalist.

I'll happily double my SLOC for most small apps if it means my app can be stdlib only.

Another way of looking at it is that your dependencies are still part of your code and to minimize those as well. It can’t easily be taken literally because who really wants to consider the Linux kernel and glibc as part of their everyday app dependencies unless writing code very close to the metal, but at the same time it can be a very useful perspective to have. Especially when you consider that you might (for security) need to code review all those dependencies as they change over time.

  • A reasonable approximation, to me, is whether or not another developer should be expected to have at least a reasonable understanding of the API of that dependency.

    E.g. we don't generally count (g)libc because a C-programmer should be familiar with the C API. We don't count Linux syscalls for the same reason, generally. But we might want to keep in mind that many APIs have dark corners that few users of the API are aware of, and so we may make exceptions.

    But the more obscure the API, the more important it is to count the complexity of the dependency as well.

    Both because it increases the amount of code your team must learn to truly understand the system, and because if it is obscure it also reduces the chance that you can hire someone to compartmentalise the need for understanding that dependency as well.

Shouldn’t you be counting the lines of code in the dependency?

  • A big problem with that is: what counts as a dependency? If I pull in Qt, am I supposed to add how many lines of code are in the parts I’m using? Many would say yes. But does using the Win32 API count? glibc? Where is the line drawn?

    • Every piece of code you rely on is a dependency.

      You may not be able to count lines of win32 code, and its awfully hard to make a patch, but if it's broken and you depend on it, your product is broken.

      There's also a multiplier that should be attached though. Most products don't have developer time or skills to write their own OS, so there's value in using someone else's even if it's probably more code than a custom built one that only satisfies the needs of the product.

  • The real reason objective measures don't work is that this is a subjective thing. When you think about the good things about code (readability, maintainability, extensibility) they don't lend themselves to mechanical analysis.

    We can proxy a little but the core problem is that the function that spits out your metrics for those actually has a hidden parameter of the audience you are writing for and the purpose it is for.

    So when the audience is highly familiar with Linux (the kernel and platform) idioms, you could choose an exotic microkernel with far fewer SLOC and actually have true lower score.

    Of course that's pointlessly edge case, but the natural simple easier to understand version of that is just using a different utility library instead of the one currently used in the codebase. This one could be smaller by far and still be worse in truth.

  • I imagine the trouble there is that you often pull in a library for some smallish, but suitable subset of what it can do.

Yes, fully agree. The only thing worse than code you have written is code you haven't.

  • To a point. Some things are complex enough that relying on a well tested and supported third-party makes way more sense than re-inventing the wheel.

    • I think a great example of that is GUI toolkits. If your program is supposed to be cross platform, using something like Qt, GTK, wxWidgets, etc. is generally preferred to writing your own GUI code.

      2 replies →