7-1-1 System and Development Environment
Programming environments have had even less benefit from research into cognetics than user interfaces have had. There is no question that modern systems are becoming increasingly complex and that programming tools need to accommodate this increasing complexity. Simple things have been made unnecessarily difficult, and we have failed to provide sufficient and sufficiently well-designed software tools needed to ease the difficulties of working in today's computer environment.
I will start with a simple example. To write a program that adds two numbers on the long-dead Apple II, you turn it on (boot time is undetectable!) and press Control-B, which gets you into BASIC. If you then type PRINT 3+4 and press Return, you get 7 instantly and painlessly. From launching BASIC to result: five seconds. As the industry is well aware, ease of use requires copious resources of memory and speed. Therefore, we know that the Apple II can operate with such dispatch and ease of use because it is a powerhouse of brute hardware: 2MHz 8-bit processor; 48K bytes of RAM (all that you could stuff in!), and a 400KB disk. A 1999 400MHz 32-bit processor with 192MB of RAM (and there's room for more!) and gigabytes of disk storage takes more than three minutes. Considering bus width and processor speed, the new machine is about 1,500 times faster than the old. Considering the time it takes to get started on writing a program, the new machine is about 36 times slower.
I asked two professional programmers to write a Visual Basic (VB) program that adds 3 + 4 and prints the result. The first began by complaining that the machine was hobbled by having only 8MB of memory and was powered by an obsolescent 75MHz 32-bit processor. Not counting the two-minute boot time, BASIC was up in 54 seconds. Then an Insert Module had to be opened, a Get Options box was opened and manipulated, a button and a form were created, and the programmer then had to type the middle line of the following:
Private sub Command1_Click () MsgBox 3 + 4 End Sub
Before this program could be used, it had to be launched and then a button clicked to make it run. Only two or three errors were made during this process, which took 3:40 (again, not counting boot time).
Another programmer, with a 75MHz 32-bit Pentium processor and 40MB of RAM, launched Visual Basic and did the same task in 28 seconds (over five times slower than the Apple II). The program, created by a slightly different process, was
Private sub Form_Load () MsgBox Str (3 + 4) End Sub
I asked the second programmer why he didn't use what the first programmer had:
MsgBox 3 + 4
He said he wasn't sure that it would work. In other words, he wasn't sure how VB worked in this case. There's nothing odd about this; like other modern computer languages, VB is huge and inconsistent in design. The rationale for its size is that it makes large projects easier, but that is no reason to make little things more difficult. To the extent that big things are made out of lots of little ones, making small tasks easier also makes the overall task easier. It is only bad language- and system design that explains why one experienced VB programmer made errors and another was not sure of the proper syntax for an elementary program. I got similar times and results with three Smalltalk programmers, thus demonstrating that it is not just VB that has these problems. Obviously, each of these languages also offers many advantages, but if they and, especially, their environments had been better designed from a human factors viewpoint, the advantages could have been had at less human cost.
Something wonderfully straightforward has been lost: in particular, the immediate feedback that humans need in order to quickly iterate their way to an effective program. I am not so naive as to think that we can keep the former simplicity in toto and achieve the level of program complexity that is now demanded, but I am certain that we can do a lot better than we have.
7-1-2 Importance of Documentation in Program Creation
Many sources explain that it is important for programmers to copiously document the code they write. Two reasons are usually given: to aid the reader of the program in understanding it (Knuth 1992, p. 99) and to make it easier to adapt the program to new circumstances (Weinberg 1971, p. 164). A typical program has an occasional line or two of comments and somewhat more frequent single-line comments attached to lines of code. Many programs are almost totally devoid of comments.
As Knuth also noted, writing the comments before or as one creates the code seems to make writing code easier, improves the design of the algorithms, lowers the number of errors and iterations required to complete a project, and also gives the advantages usually cited for providing comments. There seems to be a good cognitive reason why Knuth's impressions are correct.
When we develop algorithms and write code as experienced programmers, the process is accomplished, in part, by the cognitive unconscious. As has been noted, this mental facility can sustain contradictions. I suspect that the cause of some programming errors is that your cognitive unconscious is sustaining a contradiction between what you want to do and what the code is telling the computer to do.
However, to write out your intentions clearly in natural language forces you to make your reasoning process conscious, and it is in the cognitive conscious that contradictions most readily become apparent. Even if this hypothesis is incorrect, writing comments makes you think through the problem an extra time, in a different medium, and from another point of view.
Unfortunately, programming environments have been designed to make comments difficult to add. For example, comments in many computer languages are limited to one line; where multiple-line comments are allowed, there is often no word wrap or other features that the simplest word processors have to aid the typing process. (Two exceptions are UCSD Pascal and Oberon.) If you want to edit a paragraph-length comment in Visual Basic, a language of the 1990s, you have to word-wrap it by hand. Programmers are, according to legend, not especially proficient in spelling, so you would think that a spell-checker would be part of every programming environment, but such a facility is almost never present in a programming environment. In the current iteration of Mathematica, a generally superb program for working with mathematics, comments have been stripped out of programs and put into separate windows, a move in exactly the wrong direction. A few systems, such as Knuth's WEB (1992), were created specifically to aid the documentation process. Another approach, less sophisticated but effective, was taken by the author (Lammers 1986, p. 226).
To keep a program working, any changes to a program must be preceded by changes to the explanation. There should be no separation between programming and any other activity you do with your computer, just as we have seen that there is no need to separate other forms of computer use into applications. Experience has shown that most computer users are reluctant to even try programming. Perhaps if it were integrated into the environment so that snippets of programming would be useful without having to learn a whole programming language or a programming environment, some of the benefits of programming could be more widely realized. It would also be advantageous to be able to take capabilities from various languages and blend them, not into a potpourri, such as PL/I, but in a way analogous to what has been proposed in this book for merging applications. It might be rewarding to be able to meld LISP's structures for list processing, APL (or its progeny, J) with arrays, SNOBOL's powerful string handling, Smalltalk's inheritance and objects, and so Forth.
Cognetics can improve computer interfaces, but the blend of state-of-the-art language design and what we know of human factors has yet to be exploited to any major degree; language designers and interface experts too seldom work together. This is true even though one of the earliest books in the human-computer interface field examined this very question: Weinberg's Psychology of Computer Programming, published in 1971, was very far ahead of its time. We haven't caught up yet.