Minimize control logic, maximize application logic.
Computing is basically I-P-O.
- I = input
- P = process
- O = output
The process part is composed of two components:
1. Control logic – examples include the main program in C, Go or Node.js
2. Application logic – libraries, plugins, packages, modules
The control logic controls the overall state flow of the system so it is imperative to minimize it as much as possible (less moving parts). On the other hand, the application logic or modules should function as black boxes at the program level. You don’t care how it works internally, you only care about input parameters and its corresponding output. Modules are simply being invoked by the control logic, no more no less.
A Tale of Two Programming Paradigms
As far as programs and systems are concerned, there are only two programming paradigms: imperative and declarative programming.
1. Imperative programming is a low-level programming paradigm in contrast with declarative programming (like functional programming or flow-based programming) which lets you think in terms of more high-level abstractions
2. Imperative programming focuses on the how, declarative programming focuses on the what. As such, they tackle modularity (breaking into parts) and composition (gluing the parts together) from two different perspectives.
3. Declarative programming does not completely eliminate state (only keeps it to a minimum)
4. Turing machine is the basis of imperative programming while lambda calculus is the basis of functional programming
5. Programming paradigms all exhibit structured programming and they all promote modularity. The differences are in the implementation.
- Sequence – with imperative programming, you call functions either by value or by reference. With functional programming, it is call-by-need (aka lazy evaluation).
- Selection – “if” statement is executed in imperative programming. In functional programming, selection is an expression (which is converted to a value)
Why Functional Programming Matters (courtesy of John Hughes)
Functional programs contain no assignment statements, so variables, once given a value, never change. More generally, functional programs contain no side-effects at all. A function call can have no effect other than to compute its result. This eliminates a major source of bugs, and also makes the order of execution irrelevant – since no side-effect can change the value of an expression, it can be evaluated at any time. This relieves the programmer of the burden of prescribing the flow of control. Since expressions can be evaluated at any time,
one can freely replace variables by their values and vice versa – that is, programs are “referentially transparent”.