Functions (as in Haskell) are definitions (blueprints, templates) of a process. Everything about it is well-defined.
Traits means has-a instead of is-a relation.
Alonzo Church reduced all calculation to the notion of substitution. Evaluation: the term that results by substituting
u for each occurrence of
t (according to some domain-specific set of rules).
Equational semantics for expressions (i.e. referential transparency) is the ability to substitute a value from evaluation of an expression for expression itself (and wise versa!) without changing semantics of the program. Equation means that two sides of
= are equal, so could be substituted.
Equivalence is a partial equality in a given context. Interfaces is the way to define parts of behaviors (via Traits). Every object which implements an interface could be substituted for every other (substitute equivalent for an equivalent)
mapping a function over a function is just like currying - producing a new function with wraps the one which has been mapped on inside the one being mapped
fmap f g = f . g = \x -> g (f x)
Do the simplest working thing first. Refactor back to simplest. Just Right. Good-enough.
One editor. One high level language. Interactive shell. Keyboard shortcuts. Automate manual workflows. Make running specific tests easy. Faster you can iterate, faster you can learn. (by trial and error).
Backtracking means responding to failure by undoing the most recent choice and trying again. There may be no better way of choosing a method than to try one and see if it succeeds.
The idea of sorting a list to make information available is probably the single most important algorithmic idea in computing.
ML is a pattern-recognition, with learned/generalized from accumulated experience (evolved) representation.
Bayesian modeling in one phrase: These assumptions are not particularly realistic.
Tests also allow engineers to make changes, especially large refactorings, with significantly higher confidence. Change is the nature of everything. Change often.