I was sitting down the other day and realised that often I need to explain why a bug fix caused other issues, why it takes so long, or why regressions happen. To think through each case is mentally taxing. At some point it would be nice to have a level of abstraction that takes care of the cognitive load for me. So I came up with a first draft of what mental abstractions might useful for me. Whether or not this invades others’ minds is yet to be seen. This was done in about half an hour so please don’t take any of it seriously!!!
Class A Fixes
Fixes issue exactly as described and no more. The problem here is that the bug will probably arise again at a later time in more sinister form. This can result in the case of a bug masking another bug. If too many Class A fixes are carried out, we can end up with a huge technical debt.
Class B Fixes
Fixes issue with tacit assumptions of the real underlying problem. If the assumptions and corrective measure is wrong i.e. problem not understood, then this can end up being very time consuming. However, Class B fixes can be mitigated by documenting the assumptions and corrective measures taken.
Class C Fixes
Fixes an issue only after detailed and lengthy talk with stakeholders (can be extremely time consuming and complex that may produce the wrong conclusion anyway due to diffusion of responsibility). The idea is that the more people that are involved in issue resolution, the greater the chance something will go wrong.
Class A Regressions
A feature is broken that was functional before. Any cause of the regression that is mutually exclusive of Class C Regression causes will qualify as Class A.
Class B Regressions
Non-functional and qualitative losses or changes in functionality. E.g. slower performance, degraded build pipelines, loss of error logging, but fixes critical functional issues. Some more critical fixes may knowingly or unknowingly cause Class B regressions.
Class C Regressions
Regressions that are the direct result of a complex feature addition or enhancement. For example, in version 2, a new library was introduced to add a new features. However, the integration of the new library into the system caused other features to stop working, or to simply work differently than customer was accustomed to, with no trivial ‘fix’. Ending up in this type of scenario implies that the original implementation was not understood thoroughly before starting to make changes to the system. Purposefully diagramming a system and its relationships prior to making integration changes will be beneficial in preventing class C regressions, even if it is to demonstrate that attempting a system integration would be inappropriate in the first place.
It would be beneficial to highlight the point made about purposeful diagramming. There is no point in making diagrams of systems without a purpose. Every diagram must have a very specific purpose, otherwise it risks being completely useless to anyone, and even misleading.
Ideally I’d operate mostly in B-mode. This affords a healthy amount of autonomy without being non-critical about what I’m doing. Operating too much in A and C modes can be indicative of a lack of understanding of the systems we work with, or of fragile organisational priorities.
I’ve also had some thoughts about what the titles Junior Programmer vs Senior Programmer means to me. Almost nothing. I don’t find these titles too useful other than getting a very vague idea of experience. But experience in itself is not very useful unless you are willing to stick with the program and learn from mistakes. What I do find is that if you call yourself a Junior Programmer, you are affording yourself some reduction in responsibility and the rationalisation to operate in A-mode. But I think we should all be responsible for the code we write. We can own our successes, but we should own our mistakes too. And mistakes are only that – mistakes. We can choose not to feel bad about it, and we shouldn’t.