An extended quotation on the joys (and woes) of the craft of programming, from Brooks, F. 1974. The Mythical Man-Month.
Decoding the Value of Computer Science, an article by a non-computer-scientist on how computer science training changed the way he thinks about the rest of the world.
Dr. Richard Pattis's similar list of Quotations for Learning and Programming (much more extensive!)
The ACM's list of classic and influential books in Computer Science
Brian Hayes's article, The Post-OOP Paradigm, which is really a very readable historical survey of trends in programming.
Brian Harvey's article, Symbolic Programming vs. the AP Curriculum, which isn't so much about how to program as how to teach high-school-age students to program.
Edsger Dijkstra's 1968 Go To Statement Considered Harmful (originally a paper entitled "A Case Against the Go To Statement", but the magazine editor, in order to speed up publication, changed it to a "letter to the editor" and re-titled it). Not just about the "go to" statement, which few modern students have ever used, but about how to think about programs and why it's difficult.
Niklaus Wirth's 1971 Program Development by Stepwise Refinement, about the process of moving from a vague problem specification to a working program.
D.L. Parnas's 1972 On the Criteria To Be Used in Decomposing Systems into Modules, a seminal paper on how to break big programming problems into small ones.
All I need to know about Pair Programming I learned in Kindergarten and Strengthening the Case for Pair Programming, two articles about the "Pair Programming" approach. See also pairprogramming.com.
Extremely Successful Software, an article about using Pair Programming, lean and customer-responsive management principles, and Lisp (a predecessor of Scheme) to build software efficiently.
Taste for Makers, a beautiful essay about the role of taste and beauty in various fields (math, art, computer science, engineering, etc.)
Holding a Program in One's Head, an essay about how successful programmers work and organize their time.
Great Hackers, an essay about the existence and qualities of great programmers
"There are two ways of constructing a software
design: One way is to make it so simple that
there are obviously no deficiencies, and the
other way is to make it so complicated that there
are no obvious deficiencies. The first method is
far more difficult."
-- C.A.R. Hoare
"The human eye has an almost infinite capacity for not seeing
what it does not want to see.... Programmers, if left to their own
devices, will ignore the most glaring errors in their output -- errors
that anyone else can see in an instant."
-- Weinberg, The Psychology of Computer Programming, 1998.
George Miller's famous paper The Magical Number Seven, Plus or Minus Two. This article is not about software engineering (a phrase that hadn't been coined yet), but rather about human cognitive capacity. It suggests, however, a useful estimate of how complex any individual software module can grow before becoming difficult for humans to think about.
"For years I have been successfully using the following rule of thumb for scheduling a software task:
... for the programmer, as for the chef, the urgency of the patron may govern the scheduled completion of the task, but it cannot govern the actual completion. An omelette, promised in two minutes, may appear to be progressing nicely. But when it has not set in two minutes, the customer has two choices--wait or eat it raw. Software customers have had the same choices.
The cook has another choice; he can turn up the heat. The result is often an omelette nothing can save--burned in one part, raw in another....
Adding manpower to a late software project makes it later." -- Brooks, The Mythical Man-Month
"The world is only sparsely populated with geniuses. There is no reason to believe that the software engineering community has an inordinately large proportion of them." -- Peters, L. 1981. Software Design.
And now for something completely different: an article on how to write unmaintainable code. Tongue-in-cheek, but if you negate all the suggestions, you have some fairly good advice.
"Frequently, complexity takes the form of a hierarchy, whereby a complex system is composed of interrelated subsystems that have in turn their own subsystems, and so on, until some lowest level of elementary components is reached." -- Courtois, P. 1985. "On time and space decomposition of complex structures", Communications of the ACM.
"Complex systems will evolve from simple systems much more rapidly if there are stable intermediate forms than if there are not." -- Simon, H. 1982. The Sciences of the Artificial.
"A complex system that works is invariably found to have evolved from a simple system that worked... A complex system designed from scratch never works and cannot be patched up to make it work. You have to start over, beginning with a working simple system." -- Gall, J. 1986. Systemantics: How Systems Really Work and How They Fail.
As Dijkstra suggests, 'The technique of mastering complexity has been known since ancient times: divide et impera (divide and rule)'. When designing a complex software system, it is essential to decompose it into smaller and smaller parts, each of which we may then refine independently. In this manner, we satisfy the very real constraint that exists upon the channel capacity of human cognition: to understand any given level of a system, we need only comprehend a few parts (rather than all parts) at once." -- Grady Booch, Object-Oriented Analysis and Design, Benjamin/Cummings 1994. Embedded quote from Dijkstra, E. 1979. "Programming considered as a Human Activity", Classics in Software Engineering.
"As Miller himself observes, 'The span of absolute judgment and the span of immediate memory impose severe limitations on the amount of information that we are able to receive, process and remember. By organizing the stimulus input simultaneously into several dimensions and successively into a sequence of chunks, we manage to break ... this informational bottleneck.' In contemporary terms, we call this process chunking, or abstraction." -- Booch; embedded quote from Miller, G. 1956. The Magical Number Seven, Plus or Minus Two: Some Limits on Our Capacity for Processing Information, The Psychological Review.
"We (humans) have developed an exceptionally powerful technique for dealing with complexity. We abstract from it. Unable to master the entirety of a complex object, we choose to ignore its inessential details, dealing instead with the generalized, idealized model of the object." -- Wulf 1981?
"Complex systems can be viewed either by focusing upon things or processes; there are compelling reasons for applying object-oriented decomposition, in which we view the world as a meaningful collection of objects that collaborate to achieve some higher level behavior." -- Booch.
"Object-oriented programming is a method of implementation in which programs are organized as cooperative collections of objects, each of which represents an instance of some class, and whose classes are all members of a hierarchy of classes united via inheritance relationships." -- Booch.
"There are four major elements of [the object] model:
An abstraction is "a simplified description, or specification, of a system that emphasizes some of the system's details or properties while suppressing others. A good abstraction is one that emphasizes details that are significant to the reader or user and suppresses details that are, at least for the moment, immaterial or diversionary." -- Shaw, M. 1984. "Abstraction Techniques in Modern Programming Languages", IEEE Software.
"A concept qualifies as an abstraction only if it can be described, understood, and analyzed independently of the mechanism that will eventually be used to realize it." -- Berzins, V., Gray, M., and Naumann, D. 1986. "Abstraction-Based Software Development", Communications of the ACM.
"An abstraction denotes the essential characteristics of an object that distinguish it from all other kinds of objects and thus provide crisply defined conceptual boundaries, relative to the perspective of the viewer.
"An abstraction focuses on the outside view of an object, and so serves to separate an object's essential behavior from its implementation." -- Booch.
"Abstraction arises from a recognition of similarities between certain objects, situations, or processes in the real world, and the decision to concentrate upon these similarities and to ignore for the time being the differences." -- Hoare, C.A.R. 1972. Structured Programming.
"Structured programming appears to fall apart when applications exceed 100,000 lines or so of code." -- Stein, J. 1988. "Object-oriented Programming and Database Design", Dr. Dobb's Journal of Software Tools for the Professional Programmer.
"It is almost always incorrect to begin the decomposition of a system into modules on the basis of a flowchart. We propose instead that one begins with a list of difficult design decisions or design decisions which are likely to change. Each module is then designed to hide such a decision from the others." -- Parnas, "On the Criteria to be Used in Decomposing Systems into Modules", CACM 15:12, Dec. 1972.
"No object stands alone; every object collaborates with other objects to achieve some behavior. (Stated another way, with apologies to the poet John Donne, no object is an island....) Our design decisions about how these objects cooperate with one another define the boundaries of each abstraction and thus the responsibilities and protocol of each object." -- Booch.
"No part of a complex system should depend on the internal details of any other part." -- Ingalls, D. "The Smalltalk-76 Programming System Design and Implementation", Proceedings of the Fifth Annual ACM Symposium on Principles of Programming Languages.
"Each class must have two parts: an interface and an implementation. The interface of a class captures only its outside view, encompassing our abstraction of the behavior common to all instances of the class. The implementation of a class comprises the representation of the abstraction as well as the mechanisms that achieve the desired behavior. The interface of a class is the one place where we assert all of the assumptions that a client may make about any instances of the class; the implementation encapsulates details about which no client may make assumptions....
Encapsulation is the process of compartmentalizing the elements of an abstraction that constitute its structure and behavior; encapsulation serves to separate the contractual interface of an abstraction and its implementation." -- Booch.
"The connections between modules are the assumptions which the modules make about each other." -- Parnas, in Liskov, B. 1980. "A Design Methodology for Reliable Software Systems," Tutorial on Software Design Techniques.
A component is "the smallest set of interacting data structures and algorithms that share knowledge about how they collectively work." -- Leo Brodie, Thinking Forth, 1984.
"Ask not what you can do to your data structures, but rather ask what your data structures can do for you." -- Timothy Budd, paraphrasing JFK, in An Introduction to Object-Oriented Programming, 1997.
"Instead of a bit-grinding processor... plundering data structures, we have a universe of well-behaved objects that courteously ask each other to carry out their various desires" -- Dan Ingalls 1981, quoted in Budd, 1997.
Coupling and Cohesion, from Timothy Budd's An introduction to object-oriented programming
Polymorphism allows you to "write code today that can use things defined tomorrow without modifying the code written today." -- Booch?
I thought the following four [rules] would be enough, provided that I made a firm and constant resolution not to fail even once in the observance of them.
The acts of the mind, wherein it exerts its power over simple ideas, are chiefly these three:
You might also be interested in the 100 Best Software Engineering Books Ever. Of these, I have #2, #5, #9, #16, #28, #33, #36, #64, and probably some others on my bookshelf.
You are visitor number to this page since Jan. 13, 1997.