A good codebase is like a story.
It has an entry point, a main routine, and (hopefully) exit conditions.
I have been doing a lot of code reading. Recently with interpreted languages such as bash, python and ruby, compiled go, rust and (if I really need to) C. It’s also important to call out markup and config language, markdown/reStructuredText, json/yaml and HCL (the language for terraform).
When approaching new languages or trawling through a foreign codebase, I use a few ways to find out what the original developer intended.
The best-case scenario is to find an opensource project that has many interacting developers, a clean and idiomatic implementation (typically language or framework specific), where the code is written to acheive the intended (specific) goal.
A lot of the code that I have been reading, does not follow the best-case scenario.
In order to (try to) understand what the original intention and function of the code is (or was) for, I ask myself a few questions.
Was it some glue code that was written in a hurry to get another step in the pipeline working? Was the code put in place to improve a bottleneck?
What other code did the previous developer have exposure to, did they follow any idioms or best practices? Which ones did they break?
Did they write to a previous version of the language, libraries or operating system? Have there been updates since?
What bits of magic did they assume they could build upon, and what needed to be invented?
See also: https://engineering.tumblr.com/post/156934724082/how-i-code-now