a collection of software related principles and phrases.
general programming
- software development is managing complexity
strict call by contract
- everything that can be handled by the call contract should be handled by the call contract
- always assume valid input
- no asserts and defensive checks outside the contract
- simplify by extending the contract, not by adding code
- defensive checks are wasteful when their conditions are excluded by design
- separating input validation allows the core logic to execute faster and remain clearer
- correctness is a property of specification, not of runtime inspection
- referential transparency
- idempotency
- falsifiability
- expressions replaceable by their values
- algorithmic identity encoding. language-independent method description
algorithms expressed in purely functional terms are a canonical encoding that can be projected upwards into imperative, object-oriented, or state-based implementations, and not equivalently reversed.
- functional programming is both higher-level (not close to the machine) and lower-level (less complexity to define, since hidden state change and the consequent order dependence does not occur)
software described on three axes: procedures, functions, structures
- the first describes algorithms and evaluation
- the second describes the api in function signatures
- the third describes the carrier entities with fields
descriptive variable names that use english words
- short names are acceptable if they are real words and unambiguous in context (e.g.
count) - prefer reuse of existing variables instead of introducing new ones
- avoid identifiers with uppercase characters
- structure modules to match visible or logical boundaries
- keep the call hierarchy tidy
- reduce coupling
- avoid hidden control flow or registries. the hidden state changes make it harder to reason about and it causes order dependency and hinders clean abstraction
- intermediate formats and defined mappings between them
- triplet completion cases where any two variables define the third
- key-value tree structures
- derivative configuration files
- convention over configuration. sensible defaults to derive from avoid boilerplate configuration
- unnecessary conventions. if it is not part of the syntax, it is usually not worth following. keep it simple
- do not repeat yourself
- each component should do one thing well. much complexity in software comes from one thing trying to do two things
- principle of least surprise
- prefer positive conditions.
if (a) {b} else {c} over if (!a) {c} else {b}' - use language truth semantics consistently: avoid
x == 0 and simply use ! in c - inline when small and used at most twice; outline when large or used more than twice
- no operator overloading
- keep code to the essentials
- omitting error handling for instruction
- minimal examples that run
- minimal examples that use all features