Break it up into a few or several smaller programs that interact through clean interfaces. Then you can keep one smaller, simpler program in your head at a time, then integrate them at the end once all the smaller programs are working.
Or to put it another way…clean architecture is how you arrange the code so that you don’t need to keep ALL of it in your head at once, just the big picture and this bit here.
Totally agree and it depends on the current context of the programmer. For example, in the ACPUL language the program is split into boot images, files, modules, functions and expressions. All of these represent different levels of context encapsulation
The UNIX way would be to break things down into actual programs, where each one would be doing one thing well - and in such a way that they'd be useful as building blocks for solving other problems also.
This must not be done prematurely. Replacing function calls with processes quickly break “go to definition” and all the other conveniences or guardrails provided by your compiler toolchain.
Unfortunately been dropped into that situation. The system was constantly broken due to missing of malformated arguments. Nobody dared to change anything.
Same applies to prematurely microservicing a monolith. At least there folks seem to be sensible enough to use protobufs or json, instead of loosely typed strings.
Making as much of the program as possible pure functions and enforcing types works extremely well for this task. I would only add clean _enforced_ interfaces are key.
Break it up into a few or several smaller programs that interact through clean interfaces. Then you can keep one smaller, simpler program in your head at a time, then integrate them at the end once all the smaller programs are working.