In my first post I cheered for system thinking and understanding even the mind as a system. That can be driven to any amount of complexity, but today lets just look on two very important components: the rational and intuitive mind.
To be a good programmer you need both. Without an rational mind of course you can not construct an correct algorithm. This is the basis of any practical detail work.
But it's often overlooked that programmers using the intuitive mind as well - actually all the time. Whenever you switch context from lib to lib or even between routines (called sub in Perl), you metaphorically fold all detail knowledge you had about the previous piece of code into a general, felt notion and unzip another set of facts you know, just read or make up about the current sub. It can't be any other way, because experiments have shown, there is a single digit limit of hard facts, your rational mind can hold. In some cases it can reach 20, 25 at max.
That's why it matters to structure code in a way that: 1. you never deal with too much informations at once and 2. you prepare the reader for what is coming (the context switch) with some distinct command, identifier (name) or comment. This is what makes code intuitive. In other words: it is always a good to lower the cognitive load of code - But how we do that?
Most important are understandable abstractions, that guide thinking and usage. But this topic is a way too big for this little text and will get its own post later. Next in importance are identifiers - the names we give subs, variables, classes, packages ... Yes we heard they have to be clear, fitting, concise and if possible unique - so they lower the need for (visiting) comments and docs. But to help cognitive transitions they should also fit their surroundings. For instance an attribute named "mover" of a class named "car" should be renamed to for instance "wheel". That fits the context set by the class name, is more specific and sparks a stronger mental image.
Identifiers should invoke emotions, because that makes them memorable. Or in more neurological terms - you can connect the invoked emotions to other impressions to create an intuitive map of the code.
And you can reduce the cognitive friction even more by making terms consistent. Even smaller projects should have a little glossary file where used words are defined. And whenever this specific thing is referred too, no matter if in a variable, method or class name, it will be done only by this word. And if something is similar but not that specific thing - try hard to use another word. Especially when a method name uses 2 or 3 of these specified words - its name will work like documentation in most cases. This is why I like to start projects with writing documentation. Not only because fishing for ideas while coding is the cause of much suffering, but also because you have time to coin and define the most important terms before you start to use them.
Changing them later is tedious because its harder than just refactoring, since you have to go over many types of identifiers in many files. Normal refactoring tools would help you only partially with that, since their focus is much narrower. They rename only one variable or method name at a time. And only in one scope. You also want to have the same variable name for the same thing in different methods. Especially for arguments - which makes the API much simpler without even touching the logic.
All these practices are mentally too demanding to be done while coding. You really can only do on thing right at a time. And because you try to avoid tedious refactoring they should be done in front. On the other hand you need in most cases at least some class structure to come up with some fitting names. This is why I like to set up during the early planning stage of a project some empty dummy classes and add only certain methods, variables or comments that are essential for understanding what should go where. If you develop it in parallel with the rough outline of the user documentation and make sure you use the same words for the same things and actions in both - that also massively reduces cognitive friction. It makes the documentation more helpful and code way better understandable.
Another technique for finding good names is commenting. Quite often I just used the first best variable name and commented what i actually meant by it. Again - I was busy to figure the algorithm. Later, when glancing at the class as a whole the right name just popped out and it was just one of the words I wrote down in the comment. Having that comment, made it actually easier to find it.
If a variable has no special meaning like a counter, then "i" or "cc" is acceptable and contrasts nicely with meaningful variables with actual words in the name.
Organizing subs into parts (blocks) also helps greatly to quick scan and understand. The whole file structure should be communicating meaning, but that's also a topic for another day.
Top comments (0)