model the flow of instructions in your mind, how distant parts of the code interact together
Unless you’re hacking you usually don’t need to do this. You just need to understand what state the program is in before and after each operation. You never need to understand the whole thing at once, just understand one part at a time.
model the flow of instructions in your mind, how distant parts of the code interact together
Unless you’re hacking you usually don’t need to do this. You just need to understand what state the program is in before and after each operation. You never need to understand the whole thing at once, just understand one part at a time.
Er, what? You absolutely do need to model control flow, and how distant parts fit together. You should only think about state one operation at a time when you’re confused, or suspicious of the code you’re looking at, because step-by-step thinking is very slow and can’t support most of the operations you’d want to do on a program.
When modelling how distant parts fit together, you use abstraction. You don’t need to model how the internals of your sort function interact with other parts of your code, you just remember that it sorts things. You’re still thinking in terms of one operation at a time, just using more high-level operations.
Notice that software design best practices improve your ability to do this: separation of concerns, avoidance of mutable global variables, lack of non-obvious side effects.
From my own experience as a programmer, I think this is idealized to the point of being false. Finding a few distantly-separated, interacting regions of code which don’t respect a clean abstraction is pretty common, especially when debugging (in which case there is an abstraction but it doesn’t work).
This isn’t really possible in many cases. Many programs are resource-constrained. And the heap, IO resources, etc, are shared state. We don’t have good ways of abstracting that away. Likewise, synchronization is still a giant can of worms.
Unless you’re hacking you usually don’t need to do this. You just need to understand what state the program is in before and after each operation. You never need to understand the whole thing at once, just understand one part at a time.
Er, what? You absolutely do need to model control flow, and how distant parts fit together. You should only think about state one operation at a time when you’re confused, or suspicious of the code you’re looking at, because step-by-step thinking is very slow and can’t support most of the operations you’d want to do on a program.
When modelling how distant parts fit together, you use abstraction. You don’t need to model how the internals of your sort function interact with other parts of your code, you just remember that it sorts things. You’re still thinking in terms of one operation at a time, just using more high-level operations.
Notice that software design best practices improve your ability to do this: separation of concerns, avoidance of mutable global variables, lack of non-obvious side effects.
From my own experience as a programmer, I think this is idealized to the point of being false. Finding a few distantly-separated, interacting regions of code which don’t respect a clean abstraction is pretty common, especially when debugging (in which case there is an abstraction but it doesn’t work).
This isn’t really possible in many cases. Many programs are resource-constrained. And the heap, IO resources, etc, are shared state. We don’t have good ways of abstracting that away. Likewise, synchronization is still a giant can of worms.