You might be interested in Fred Brooks’ seminal essay, No Silver Bullet—Essence and Accident in Software Engineering. In it, he distinguishes between essential complexity and accidental complexity. Essential complexity is complexity that comes from the problem domain. It cannot be factored out of the program, and any attempt to do so will likely introduce bugs. Accidental complexity is complexity that arises from details of the implementation, and which can be simplified out of the implementation.
A good example of accidental complexity is memory management. A good chunk of programmer effort in languages like C and C++ goes towards ensuring that memory is managed properly, and that the program returns memory to the operating system when it is finished using it. Memory managed languages take that burden away from the programmer and place it either with the compiler (in the case of Rust’s borrow checker) or with the runtime environment (in the case of garbage collected languages like Java, or Python). The effect of this has been a significant reduction in accidental complexity (at the cost of some performance), with a commensurate increase in programmer productivity.
You might be interested in Fred Brooks’ seminal essay, No Silver Bullet—Essence and Accident in Software Engineering. In it, he distinguishes between essential complexity and accidental complexity. Essential complexity is complexity that comes from the problem domain. It cannot be factored out of the program, and any attempt to do so will likely introduce bugs. Accidental complexity is complexity that arises from details of the implementation, and which can be simplified out of the implementation.
A good example of accidental complexity is memory management. A good chunk of programmer effort in languages like C and C++ goes towards ensuring that memory is managed properly, and that the program returns memory to the operating system when it is finished using it. Memory managed languages take that burden away from the programmer and place it either with the compiler (in the case of Rust’s borrow checker) or with the runtime environment (in the case of garbage collected languages like Java, or Python). The effect of this has been a significant reduction in accidental complexity (at the cost of some performance), with a commensurate increase in programmer productivity.
Thanks a lot. Interesting essay and interesting concepts.