This will be objected to and ignored by most, but take it from an old hacker who has production code in place decades after designing, writing, building, testing, and delivering it:
Try/Catch, thrown exceptions, and assert() are things I associate with poorly designed code — code likely to fail in non-trivial production. Avoid these idioms. If possible, avoid languages that support them. Suspect development paradigms that blissfully support these things.
By their nature, ‘exceptions’ are pathological instances of uncaught bugs. The discipline of putting these things in place violates an old rule of thumb as to how code should behave. It is something of a prior commitment to the acceptance of bugs. Bugs are enemy number one. A single defect can ruin an entire system that took man-years to build. A single defect opens security defects that can annihilate systems and cause tragic stress in individuals who, empirically, we know have no effective backups to roll back to. Serious code is serious business. Bugs are No Bueno.
And yeah, these are skewed to procedural rules of thumb. Guess what? It’s because they work. Most all of the code you actually use is built that way. Phone apps (not built that way) need to be updated constantly by mandate from Google and Apple. I still use Microsoft Image Composer, written in C. The binary release I use is, as of 2024, 27 years old. These days, languages and platforms themselves don’t last more than a few years, let alone the things built on them.
A few old rules of thumb:
Single Responsibility Principle: A function should do one thing well.
Single Point of Entry and Exit: A function should have a single point of entry and a single point of exit.
Error Handling: Always check and deal appropriately with return values.
Re-entrancy: All code should be re-entrant. State should never be global.
Murphy’s Law: “Anything that can go wrong will go wrong.”
Keep It Simple, Stupid (KISS): Simplicity should be a key goal in design, and unnecessary complexity should be avoided.
You Aren't Gonna Need It (YAGNI): Don’t add functionality until it is necessary.
Don't Repeat Yourself (DRY): Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.
Separation of Concerns: Different concerns should be separated to reduce complexity and improve maintainability.
Modularity: Break the code into modules or smaller components that can be developed, tested, and understood independently.
Encapsulation: Encapsulate the details that are likely to change.
Consistency: Follow consistent coding conventions and practices.
Code Readability: Code should be written to be read by humans first and computers second.
Avoid Premature Optimization: Optimize later, focusing first on code correctness and simplicity.
Re: Murphy’s law, “Anything that can go wrong will go wrong” The article on Wikipedia, ironically, gets it wrong. I wrote about it here while writing this response:
** This applies to code blocks as well.
No comments:
Post a Comment