Code Dependencies

How people structure their code, and how a function list can help you write maintainable code.

Some programmers divide their code up into small files, then include these files here and there, ending up with files depending on other files, aka. spagetti, where you have to do detective work in order to figure out where some definition is hiding, and variables are easily shadowed/overwritten.
Others divide their code up into modules, that depend on each other.
Even if you are using modules (that depend on each other), you sill have spaghetti all over the place.
The correct way to structure the code is to have it all in one-single-file, until some part of the file is fully independent from the rest of the code, and only then you can break it out into a module.
For example in a Math library, each function in the Math library do not depend on any other function in your code, your code only depend on the Math library, not vice versa, then you can break those math functions out into a library or module.

If you have to pass objects, that are more then just basic configuration, into a module, then the module code should probably be in the main file, and the object should be a scoped variable instead of passed around between modules.

If you have a module, that is only used in your program, and has no reusability outside your program, then it's probably best to keep that too in the main file, as breaking it out will probably lead to you having to pass program state and objects around. Meaning extra work for no good reason.

If you lift something out as a standalone module, and you start to use it in other programs, but you have to add new functionality into the module for each new program it interacts with, then it's much better to just copy & paste the code into each program and make the program specific customizations only in the programs that need it.

I know you probably spilled your coffee when you read the solution was a single big main file. But bear with me please. I acknowledge that one problem when you do-not split the code up into arbitrary pieces, is that the main file can become very big, several thousands lines, and scrolling back and forth becomes painful. The solution is to have a function list. Then instead of scrolling or searching, you just click on the function, and the editor scrolls to it. A simple solution, that should solve most of your issues with big files.

Different coding paradigms ...

You probably hate me already, but if proposing a single huge files is not enough, I will also talk shit about your favourite programming paradigm.

Both functional programmers (FP) and those doing objective oriented programming (OOP) both agrees that functions should only do one thing, but if you take that into the extreme you should be programming assembly code. And OOP programmers make classes that depends on other classes, and FP programmers make functions that use other functions, both paradigms end up in spaghetti code, that you need to unravel in order to understand what the code actually does, where all functions or classes are global, or modules disguised as globals.

The correct way is to make use of lexical scope, meaning that you hide everything by default.

One acronym that many programmer have as their mantra is "DRY" (don't repeat yourself), but used too early, you get premature abstractions.
Instead, before you start to think about abstractions, try to get a working prototype, then when the program is almost finished, that's when you get rid of side effects, mutability, and impure functions, and apply DRY to make sure that when you later need to change something in the code, you only have to change it at one place. While prototyping it's totally fine to have shitty code! Like for example global variables. One trick I use, is to write global variables in ALL_CAPS so they stand out, and are easy to spot later.
One benefit when not abstracting prematurely is that you have to think less about naming things, it will be much easier to name things when you are wrapping things up for production, as each function will have a clear purpose, and what the function does is mostly concrete (it's interesting that in English concrete is used both for "capable of being perceived", and "strong hard building material").


Written by September 05, 2019.


Follow me via RSS:   RSS https://zäta.com/rss_en.xml (copy to feed-reader)
or Github:   Github https://github.com/Z3TA