This chapter discusses some general ideas about computer programming. A computer program is a set of instructions that a computer can follow. The instructions are used to represent a problem and the steps needed to solve the problem.
A computer program may be designed to interact with a person, so that the person and a computer work together to solve a problem. Or a program may be designed to interact with a machine, such as an automated production facility or data-gathering instrumentation equipment.
A computer program is a detailed set of step-by-step instructions that a computer can interpret and carry out. That is, a computer program tells the computer hardware what to do. The process of creating a computer program is called programming. The terms computer program and computer software are used interchangeably.
Traditionally, computer programming has meant the process of designing and writing a computer program in a programming language, such as a machine language, an assembler language, or a higher level programming language (e.g., Ada, BASIC, C, C++). There are hundreds of different higher-level programming languages designed to fit the specific needs of programmers working in different problem domains.
Over the years, the traditional definition of computer programming has gradually been modified. Here are three somewhat distinct levels or types of computer programming:
It is possible to use a computer without knowing much about computer programming. However, many computer users find that their expertise in using a computer to help solve problems is greatly increased by learning and understanding computer programming at one or more of these three levels.
The first computers were designed to help solve math, science, and engineering types of problems. For the earliest computers, programming consisted of rewiring the machine. A computer was rewired to be able to solve a particular type of problem. Plug boards were used, much like the plug boards used in early telephone systems.
It was a major breakthrough when the idea of storing a computer program in the computer memory was developed. The program could then be changed by just changing the contents of the computer memory. Indeed, the instructions in a computer program could be designed to make changes to the computer program! This "stored program" change in the human-machine interface made it easy to store computer programs for reuse at a later date and for transporting them to other computer sites. The programs could be stored on punched paper tape, punch cards, or magnetic tape.
The mechanics of programming in the early days of computers were not simple because the human-machine interface was not well developed. Programming was done at the machine-language level. A machine is constructed to "understand" about 100 to 200 different numbered instructions, for example, 001, 002, 003, 004, and so on. The instructions are designed to work on the contents of individual computer memory locations, and each instruction accomplishes a small, specific task. For example, an instruction might change the sign of a number. A different instruction might compare two different memory locations to see if they are equal. Still another instruction might add the number 1 to a given memory location. The smallest error in indicating what instruction is to be done or what memory locations it is to affect can lead to completely wrong results. It is really easy to make a simple mistake, such as telling the computer to do instruction 187 when you really want the computer to do instruction 178. It is difficult to detect and correct errors when one is programming at the machine-language level.
Gradually the human-machine interface in computer programming was improved. A simple example was the development of mnemonics for the instructions and variable names for memory locations. Words, such as ADD, SUB, MUL, and DIV, are easier to remember than numeric codes for instructions. Variable names, such as LENGTH and WIDTH, are easier to work with than memory location addresses, such as memory location 21834 and memory location 02642. Computer programs were developed that translated the mnemonic instructions and the variable names into appropriate machine-language instructions and specific memory location addresses. The translating programs were called assemblers, and the languages themselves were called assembler languages or assembly languages.
During the early to mid-1950s, still better human-machine interfaces were developed to help programmers. These were called higher level programming languages. FORTRAN (standing for FORmula TRANslation) was developed over a span of time--from 1954 to 1957. This language was specifically developed for use by scientists and engineers. Many different versions of this language have been developed since then, and FORTRAN is still a widely used programming language in the science and engineering fields. FORTRAN is based on the language of algebra. A person who knows high school algebra usually finds that it is relatively easy to learn to use FORTRAN.
The FORTRAN programming language is representative of a key idea in the computer field. Not only can people develop better human-machine interfaces but they can also develop interfaces to suit the needs of specific domains. COBOL was developed for programmers working on business problems. BASIC was developed as a math tool for college students. The key idea is that a person who has considerable knowledge in a domain can build on this knowledge through learning a programming language specifically designed to help solve problems in that domain.
[[That is, there is transfer of learning from a domain into learning to use a programming language that was designed to help solve problems within the domain. It is interesting to consider the opposite direction of transfer. Suppose that one has never studied business accounting. One learns to use a spreadsheet. By doing so, one may learn something about business accounting. Or, if one subsequently takes a business accounting course, they may find that a significant amount of transfer of learning occurs while taking the course.]]
Over the years, more and more higher level programming languages have been developed. Now there are hundreds of different programming languages. Superficially, these general-purpose, higher level programming languages seem to differ quite a bit from each other. However, in many ways, they share much in common. Some of the commonality is discussed in the following section.
A computer program has two main parts. First, it contains a representation of the problem, including the data that is to be input, stored, manipulated, and output. This is called a data structure. Second, it contains detailed instructions telling the computer exactly what to do with the problem representation and the data. This is called a control structure. Thus, a computer program consists of a combination of a data structure and a control structure.
The initial higher level programming languages, such as FORTRAN and COBOL, were oriented toward somewhat specific domains of problem solving. FORTRAN was designed to help a programmer create the types of data structures and control structures needed to solve math, science, and engineering problems. COBOL was designed to help the programmer create the types of data structures and control structures needed to solve business problems.
As use of computers spread to other fields, people began to develop software to fit the specific needs of problem solvers in these fields. This has helped contribute to the current situation in which there are a number of general-purpose programming languages and there are a number of productivity tools with built-in programming languages.
A productivity tool is often designed to make it easy to represent certain kinds of problems. For example, a graphic artist needs to represent figures that contain lines, rectangles, circles, and other geometric shapes. Thus, a productivity tool designed for graphic artists contains good provisions for representing these types of figures. The graphic artist may want to view a figure from different perspectives. Thus, a productivity tool designed for graphic artists contains good provisions for manipulating a figure to show it from different perspectives.
The data structures and control structures needed by a graphic artist are certainly different from those needed by a musician. The musician uses musical notation to represent music. A musician needs to hear the music in addition to viewing its score. The musician needs easy provisions for manipulating and combining the sound from a number of different musical instruments. Thus, a productivity tool designed for musicians contains provisions to make it easy to accomplish all of these tasks.
Earlier parts of this book discussed BBRs and chunking. The use of chunking in problem solving plays a central role in the field of computer programming.
All programming languages support a particular type of chunking or BBRs that computer scientists call a procedure. A procedure is a self-contained set of programming language instructions that can be treated as a unit. A procedure is often called a subprogram or a subroutine. A computer program is usually designed as a collection of procedures that have been appropriately linked together to solve a problem or accomplish a task.
Computer programmers are taught to think in terms of cognitively manageable units of computer code. Remember, the human mind can deal with a concept as a unit or a chunk far more easily than it can deal with the details of a concept. A cognitively manageable unit of computer code focuses on a single concept or task. A cognitively manageable chunk of code needs to be short enough and simple enough so that it can be easily tested and debugged (have its errors removed).
Thus, computer programmers learn to think in terms of developing cognitively manageable procedures. They learn to solve problems by using such procedures. This overall process is called procedural thinking. It is one of the most important ideas in computer programming. It is such an important idea that some definitions of computer literacy include the specification that to be computer literate, a person has to understand and make use of procedural thinking.
[[The statements about procedural thinking are somewhat dated. Object-oriented thinking is different than procedural thinking.]]
The early programming languages provided rather limited aids to the programmer working to represent a problem. Two major types of advances have occurred. One type of progress is seen in productivity tools, such as a word processor, database, or spreadsheet. An entire application program is designed for the representation of a particular type of problem. A word processor, for example, is designed to make it easy to represent the types of information that writers must deal with. A spreadsheet is designed to make it easy to represent certain types of business problems.
A second major breakthrough was the development of object-oriented programming. Some examples of objects that a programmer might want to include in a program could be a pull-down menu, a button, and a scrolling field. Each of these objects varies in physical size, placement on the screen, and how it is to interact with the computer user. An object-oriented programming language contains a number of built-in objects. With a few keystrokes, the programmer designates the specifics of an object that possesses an underlying computer programming code of possibly thousands of lines in length. In an object-oriented programming language, the programmer can also easily create new objects.
Initially, object-oriented programming was considered to be an esoteric subject. We now have reached the stage where a number of programming languages and computer applications contain object-oriented provisions that are easy to use. For example, in an engineering drawing program there are good provisions to create objects consisting of combinations of circles, rectangles, and other geometric shapes. These objects can easily be sized, rotated, and positioned as needed when undertaking a drawing task.
Now, object-oriented programming has come to the forefront, proving to be an important key to building on the previous work of other people. If an object is appropriately defined in a programming language, it can be used by any programmer who has need for such an object.
As computers started to become commercially available during the early 1950s, many colleges and universities developed programs of study in this field. Many of the early programs of study focused on computer programming. Thus, a student might take a beginning and advanced course in assembler-language programming, a beginning and advanced course in FORTRAN programming, and a beginning and advanced course in COBOL programming. The focus of the instruction was on the specific tool, rather than on problem-solving ideas that cut across different programming languages and domains. Now, such a curriculum is considered archaic.
[[Computing Curricula 2001--DRAFT (March 6, 2000)--Chapter 2 Lessons from Past Reports[Online]. Accessed 11/12/01: http://www.computer.org/education/
Gradually it became clear that all programming languages share a lot in common. Moreover, it became clear that a number of problem solving and programming ideas are applicable to every computer programming task. A field of study and research called software engineering began to develop. Software engineering includes computer programming, but it also includes the study of data structures, control structures, the mathematics of solving problems via computer, and a number of different programming practices and ideas that are independent of any particular programming language. For example, in many different problems it is necessary to sort a table of data into alphabetical or numerical order. There are many different ways to do this. Some are much faster than others, and this partly depends on the circumstances of the particular problem. Thus, the study of sorting algorithms is a standard topic in software engineering.
In the early history of programming, computer programs tended to be relatively short. One person could fully understand the problem to be solved, write and test the software, and correct errors that were later found by users of the software. This gradually changed. It is estimated that it took the equivalent of 20 person-years of effort [[during 1954-57]] to develop the FORTRAN programming language and the program to translate from it into machine language for one particular machine. A team of some of the best programmers in the world worked on this project for several years.
Two important ideas emerged as programmers struggled to cope with large and complex projects. First, a large program should be constructed from small, self-contained modules (subprograms) that can be independently written and tested. A subprogram needs to be short enough and simple enough so that a programmer can fully understand it and take responsibility for that piece of the overall program.
Second, the idea of structured programming was developed. Computer programming became more of a systematic science. Programmers learned to think of a program as having structure, with the pieces of this structure being created, tested, and assembled in a systematic manner.
A careful analysis of computer programs reveals that every program can be built from three basic types of structures or constructs: sequence, selection, and repetition.
Software engineering is now a well-developed discipline. It is both embedded in computer and information science coursework and is taught in separate courses.
[[Guide to the Software Engineering Body of Knowledge (SWEBOK) [Online]. Accessed 11/12/01: http://www.swebok.org/.]]
Does skill in one higher-level programming language transfer to learning and using a different higher-level programming language? This will be discussed in the current section.
Transfer of computer-programming learning can also be examined for transfer to noncomputer problem-solving environments. This is covered in the next section.
A computer program consists of data structures and control structures that are designed to solve some type of problem. A skilled computer programmer is adept at creating the data structures and control structures for solving problems in one or more domains. This requires three types of expertise:
The first of these three types of expertise is domain specific. It requires a great deal of knowledge about the specific domain. Research suggests that there is not too much transfer of learning of such domain-specific knowledge from one domain to another. Of course, an exception occurs when two domains contain a considerable overlap. For example, theoretical physics overlaps strongly with mathematics. Thus, a skilled mathematician may be able to make a major contribution toward solving problems in theoretical physics.
Considerable transfer of learning occurs in the second and third types of expertise in the preceding list. This transfer occurs as one moves among different hardware and software environments. It occurs as one moves among various productivity tools and among various programming languages. The transfer can be both low-road (automaticity) and high-road (reflectivity) transfer.
For example, suppose that you have learned a programming language that is object oriented and contains a scrolling field as one of the built-in objects. In this programming language, as you conceptualize the writing of a program to solve a problem, you are mindfully aware that a scrolling field is available as a BBR. You may make use of this BBR often, as you deal with a wide range of problems.
Now, suppose that you need to program in a different programming language that is not object oriented and does not contain a scrolling field as a built-in object. If the types of problems that you want to solve require a variety of scrolling fields, your immediate response to the situation will be to find or to write a procedure (a subprogram) that creates and manipulates scrolling fields. That is, you will add this BBR to the programming-language environment in which you are working.
It takes a great deal of training and experience to learn the many and varied ways to represent problems in a computer-programming environment. The actual facilities that are built into different programming languages for the representation of problems vary from language to language. But, once you have mastered the basic ideas of problem representation, most of what you have learned will transfer from language to language.
A structured programming language encourages a type of modularity (a type of structure) in the program design. Structured programming is an idea that cuts across all programming languages. Thus, once you master the concept of structured programming, you can easily adjust your ideas to any programming environment.
To summarize, software engineering can be thought of as the science of computer programming. Computer programming involves representing a problem and representing the steps needed to solve the problem. The details of both the representation of a problem and of the steps to solve a problem will vary among different programming languages. A problem may be very easy to solve in one language and difficult to solve in another, or vice versa. However, the general underlying concepts transfer from language to language. This transfer is enhanced if the learner strives for learning that will transfer. Both the low-road and the high-road mechanisms are applicable.
Computer programming can be thought of as a type of problem solving in which the main resources are a computer and the computer programmers. You might think that the problem-solving skills needed in this environment easily transfer to solving problems in other environments that do not depend on computer programming.
There have been many research studies on the transfer of problem-solving skills from computer programming to other environments. In the typical study, some students (the experimental group) learn computer programming while other students (the control group) spend their time on some other learning tasks. The groups are matched on the basis of their initial overall skills in problem solving that do not involve the use of computers. After the "treatment," both groups are tested for their general noncomputer problem-solving skills.
The early researchers were puzzled by the rather consistent results indicating that little or no transfer of problem-solving learning surfaced in such studies. Salomon and Perkins (1988) and Perkins (1995) summarize the early research literature in this field. They describe a low-road/high-road transfer theory. They analyze the research studies on the basis of whether the treatment was powerful enough to lead to low-road and/or high-road transfer. Their conclusion is that the treatment in these types of studies has seldom been adequate to lead to either low-road or high-road transfer.
Based on an analysis of the research literature and their own studies, Salomon and Perkins conclude that there will be transfer of learning in problem solving if computer programming is taught in a manner that helps transfer to occur. That is, transfer of learning will occur if the instruction meets the conditions that are needed for either low-road transfer or high-road transfer.
It is easy to develop a modest skill level in one, two, or even all three of the levels of computer programming discussed near the beginning of this chapter. With appropriate instruction and practice, elementary school students can do this. Even a modest level of programming competence can contribute significantly to your overall level of expertise in using computers in many different domains.
Many studies have been designed to determine the characteristics or types of native skills that help a person become a good computer programmer. As might be expected, the logical-mathematical category of intelligence tends to correlate highly with success as a computer programmer. However, musical intelligence also tends to correlate highly. And, of course, persistence and attention to detail are critical.
Nowadays, a considerable amount of computer programming is done by teams of people. Interpersonal skills and communication skills are important in this type of programming environment.
By definition, the experts in any domain are able to outperform people who are merely competent or who are novices in the field. Computer programming is a domain in which people with a high level of expertise really stand out relative to people who are merely competent in the domain. The expert can undertake and accomplish tasks that are well beyond the capabilities of a person who is a competent programmer. This helps explain the high salaries that such experts can obtain.
As with any domain, it is possible to learn computer programming on your own. However, software engineering is now a well-developed field of study. Many different computer-science programs of study include software engineering coursework. Such coursework can be very helpful in developing expertise as a programmer.