Things I learnt the hard way in thirty years of software development
Type systems exist on a spectrum. A rich type system is better at documenting your code than comments are if the compiler and it&#x27;s type system are sound: the comments can be wrong, the types cannot.<p>A sufficiently expressive type system can check your logic for you. Push as much of your propositions and predicates into the types as possible.<p>Data types are better than exceptions, return codes, etc for the majority of unexceptional cases. Conditions and restarts are better than exceptions. Sometimes crashing is not an option when your computer is flying in the air with a human.<p>In addition to specifications -- often a bunch of boxes with arrows will not be sufficient. There are a range of tools to check your designs from automated model checking to interactive proofs. When the problem is difficult to understand on its own then the solution is probably even harder -- a good sign you should consider using one of these tools to make the problem clear and guide you to the right solution.