If you have a hammer, everything looks like a nail. If you're a mathemetician, everything looks like a math problem.

.

We're not really that special.

.

.

The programmer is in the unique position that his is the only discipline and profession in which such a gigantic ratio, which totally baffles our imagination, has to be bridged by a single technology. He has to be able to think in terms of conceptual hierarchies that are much deeper than a single mind ever needed to face before.

I disagree.

A city planner does not need to know or care how to make bricks. An application developer does not need to know or care how HashMap<> internals work (well, not after they pass the interview at least).

An identical program can run on 1MB of data or 1TB of data, without changing it or adding layers of abstraction. A city with 4x as many people is not just 4 1x cities stuck together.

Complexity and the number of abstraction levels do not necessarily scale with system size in elementary particles.

.

To this I should add that, to the extent that we view ourselves as mechanisms, we view ourselves primarily as analogue devices: if we push a little harder we expect to do a little better. Very often the behaviour is not only a continuous but even a monotonic function: [...]

Of interest is that while this view may be popular, I think it's beginning to become apparent that it's not entirely accurate. Besides more well-known effects like overtraining, there's also reduced productivity with too-high work hours, reduced creativity in the face of excessive pressure, etc. And it's not just the "monotonic" part that's questionable -- things like burnout and the traditional "mid-life crisis" and mental breakdowns hint that we're not even particularly continuous.

In the discrete world of computing, there is no meaningful metric in which "small" changes and "small" effects go hand in hand, and there never will be.

This also applies to complex mechanical systems, and to anything with DNA. Whatever mutations cause cancer can't be that big a change, or they wouldn't happen so often.

.

The nice thing of this simple change of vocabulary is that it has such a profound effect: while, before, a program with only one bug used to be "almost correct", afterwards a program with an error is just "wrong" (because in error).

This is very silly. Not all bugs/errors render a program wholly useless.

.

[Don't anthropomorphise programs/computers.] ... ...deal with all computations possible under control of a given program by ignoring them and working with the program. We must learn to work with program texts while (temporarily) ignoring that they admit the interpretation of executable code.

This depends entirely on what you're doing. Are you trying to study computation using some program as an example, or are you trying to accompilsh some real-world effect with that program?

A programming language, with its formal syntax and with the proof rules that define its semantics, is a formal system for which program execution provides only a model. It is well-known that formal systems should be dealt with in their own right, and not in terms of a specific model. And, again, the corollary is that we should reason about programs without even mentioning their possible "behaviours".

Since the current context is the evils of anthropomorphization, what is the assumed use that "formal system" is a better (more useful) model than "intentional actor"? Insistence on formality becomes especially weak when the system can't be formally defined, either because the behavior depends too much on (unknown) input data or because the formal spec is intractable.

.

.

Right from the beginning, and all through the course, we stress that the programmer's task is not just to write down a program, but that his main task is to give a formal proof that the program he proposes meets the equally formal functional specification.

We've since discovered that all this will accomplish is to pass the buck to the people who wrote the invariably-buggy (I mean, erroneous) spec. Which since it's fully formal, could just be mechanically translated into a program anyway.

.

.

I think some of the things I learned were pretty good (and in a pretty good order): use of mathematical induction to prove that recursive algorithms work (introductory); complexity analysis (same introductory course); lambda calculus and compilers (4xx level). That's certainly better than trying to focus on formal methods, when all they can accomplish is to move the informality. I'd have also benefited from something on creating and refining models, or turning a problem into a spec (because really, building the right thing is always harder than building the thing right). For CS rather than CompEng, I'd also suggest more depth on discrete math than I took, and whatever kind of math is appropriate for distributed systems (queues and graphs and flow rates and stuff).