The book Object Thinking makes a very good explanation of the divide between two different, antagonistic modes of thinking. The formalist tradition (in software) values logic and mathematics as design tools. A formalist thinks that documents have objective, intrinsic meaning. Think “design documents”; think “specifications”.
The empirical tradition (the book calls it hermeneutics, but I will stick to this less formal name :-) values experimentation. Empiricists hold that the meaning of a document is a shared, temporary convention between the author and the readers. Think “user story”; think CRC cards; think “quick design session on the whiteboard.”
The empiriricists brought us Lisp; the formalists brought us Haskell. The formalists brought us Algol, Pascal, Ada. The empiricists brought us C, Perl, Smalltalk.
Empiricists like to explain things with anthropomorphism: “this object knows this and wants to talk to that other object…” The formalists detest anthropomorphism; see these quotes from Dijkstra.
As a former minor student of the best formalist tradition there is, and a current student of the Object Thinking tradition, I think I’m qualified to comment. Please don’t take my notes as meaning that the formalist tradition sucks; I certainly don’t think this. I’m interested in highlighting differences. I think a good developer should learn from both schools.
Formalists aim to bring clarity of thought by leveraging mathematical thinking.
Object thinking aims to bring clarity of thought by leveraging spatial reasoning, metaphor, intuition, and other modes of thinking.
It is well known that mathematical thinking is powerful. It’s also more difficult to learn and use. One example that was a favourite of Dijkstra is the problem of covering a chessboard with dominoes when the opposite corners of the chessboards were removed. If we try to prove that it’s impossible by “trying” to do it or simulating it, we’d quickly get bogged down. On the other hand, there’s a very simple and nice proof that shows that it’s impossible. Once you get that idea, you have power :-)
An even more striking example is in this note from Dijkstra on the proof method called “pigeonhole principle”. Dijkstra finds that the name “pigeon-hole principle” is unfortunate, as is the idea to imagine “holes” and a process of filling them with “pigeons” until you find that some pigeon has no hole. The process is vivid and easy to understand; yet it is limiting. Dijkstra shows in this note how to define the principle in a more simple and powerful way:
For a non-empty, finite bag of numbers, the maximum value is at least the average value.
This formulation is simple (but not easy!) Armed with this formulation, Dijkstra explains how he used this principle to solve on the spot a combinatorial problem about Totocalcio that a collegue of his could not solve with pen and paper. He also explains how he used it to solve a generalization of the problem, which would not be easy to prove with the “object-oriented” version of the principle.
I think this note presents the contrast between formalism and empiricism vividly. If you put in the effort to internalize the formal tool, that which was difficult becomes easy, and you can solve a whole new level of problems.
On the other hand, the formalists do now always win :-) Formalists reject the idea of making tests the cornerstone of software development. In my opinion they are squarely wrong; examples are the primary tools to do software development, and you can’t even understand if a specification is correct until you *test* it with examples.
The one thing that boths camps have in common is that they are both minority arts. Real OOP is almost as rare as Dijkstra-style program derivation. The common industrial practice is whateverism :-)