By everyone, I mean every voting member of a free democratic society. I'll describe know below. Here is what:
I do not believe that people will know these facts if we simply tell them or make them memorize the sentences above, or even make them read comp.risks. In order to know these facts, people must GRAPPLE with software development by actually programming. And by programming, I mean programming in the large sense as Abelson and Sussman or Thompson and Ritchie would use the term.
If people do this (grapple with the issues by learning to program) they will also gain far more than knowledge of the 8 facts above. They will gain a mental tool that helps in clear, careful thinking and problem solving of any sort. They will gain a respect for complexity and techniques to handle complexity.
The following is my attempt to explain to laymen what can be gained from one good course in Computer Science.
In order to solve a problem on a computer, it is necessary to understand exactly what the nature of the problem is. This requires the development of the ability to transform loosely worded descriptions into precise specifications. Once this has been done, most problems are too complex to be handled in toto. It is necessary to divide the problem into a number of individual parts that are manageable, solve these parts and then verify that reassembling these solutions together properly does in fact solve the original problem. Finally, the solution must be documented so that other human beings can understand the solution and be convinced of its validity. Developing an algorithm to solve a problem requires the ability to abstract the essence of the problem from the details. However, once the appropriate abstraction has been discovered and an algorithm developed, the computer scientist must return to the details considering every possible contingency that may arise during the sequential or concurrent execution of a number of complex processes. The execution of these processes is a dynamic event that will take place sometime after the solution has been conceptualized and on input values usually not known precisely. In order to deal with this dynamic complexity, computer scientists must develop the ability to discern statements of static, invariant relationships that will hold at various points in the problem solution independent of the initial input values.
Formulating an algorithm to solve a problem and then programming it for a computer is a bit like preparing a lecture on the problem for an extremely literal minded individual who knows nothing. Ideas must be organized and presented in a linear fashion. Everything must be stated precisely. Attempting to do this is an active, creative process that invariably leads to a better understanding of the original problem. We use the phrase 'algorithmic thinking' to refer to this creative process of understanding and precise expression necessary to design and communicate an algorithm to a person or computer. Once the algorithmic way of thinking has been mastered, it may be applied to questions of all sorts, independently of any desire to obtain a solution from a computer. It becomes a mental tool that can be used to counteract the natural human tendency for quick and easy, but sometimes careless and sloppy, thought. This is not to say that the algorithmic mode of thinking is a panacea. Obviously, there are important questions which require other types of thinking. Algorithmic thinking is, nonetheless, a very powerful tool when added to other modes of thought.
At present the disparity between the level and structures used in human thought and those available even in our so-called high level computer languages is so great that all but the simplest programs are born containing errors called bugs. This leads to practice in tracking down bugs in extremely complex, dynamic environments. It also leads to an attempt to develop methodologies to avoid bugs, and realizing that avoidance will not be completely successful, the development of techniques to help find the anticipated but unavoidable bugs. This practice provides good exercise for anyone who lives in a world that, at times, seems to be governed by Murphy's Law, which states, "anything that can go wrong will go wrong."
The computer itself is an important general tool. It is already used in almost every discipline. Many of the present uses are rather pedestrian, but nonetheless important, applications of a computer's capabilities. Word processing, communication, indexing, and information retrieval are some examples. More creative applications of computers will require efforts by individuals with knowledge of some depth in both the application discipline and computer science. As computer scientists improve their understanding of methods to index and transform information and as users learn of the full capabilities of computer systems (as opposed to the limitations of particular software packages), we will see the realization of computer systems that extend our mental capabilities in much more profound ways than we have seen heretofore.
To me this means doing some programming. It could be largely reading programs and doing modifications (enough to see how easy it is to overlook a bug). But the goal should be for everyone to UNDERSTAND the following:
- Computer Software Systems almost always contain errors; but NOT because software developers are careless, stupid, or lazy.
- Specification is hard.
- Given a specification, writing a program that correctly realizes that specification is hard.
- Twice as much code does NOT make software twice as reliable.
- Twice as many programmers do NOT allow reliable software development in half the time.
- Although computers are very fast, there are many important problems that do NOT yield to 'brute force' solutions.
- Even with 'clever' algorithms, many important problems do NOT scale in a linear fashion.