The following ten patterns form a pattern language. The relationships between them will be discussed at the end. They will be referred to, however, from within each discussion. In this case we use an italic face to highlight the name of the pattern referred to.
Some of the patterns below have numbers assigned. They have been submitted to the Pedagogical Patterns Project. Many educators are getting involved in this effort. You can find the current list of patterns and more information by clicking the above link. The others have been submitted but have either not been accepted, or have not had numbers assigned. You might consider gettin involved in this effort if you are an educator.
At the end of the list of patterns I discuss how they fit together into a pattern language.
Pedagogical Pattern #30
(Version 1.2, October 1998)
Giving a student or group of students a large artifact that is generally sound but with carefully introduced flaws can both introduce a complex topic early and serve as a way to introduce error analysis and correction. Students are asked to repair and discuss the artifact.
The pattern can be used in several courses and at several levels. It can be used very early in programming courses and in teaching analysis and design. It can also be used to show the overall structure of a solution methodology.
We often need to introduce students to a new field requiring mastery of several topics. Students often fail to see how the topics fit together when introduced sequentially. They also often fail to have a grasp of the means of locating and correcting errors.
Fixing a larger artifact than can be created by students is generally within their grasp. It gives them a better sense of scale of interesting problems and permits them to integrate a number of issues into the solution of a single problem.
Students can benefit from seeing larger problems than they can solve at their current state of development. They also need critical analysis skills and the ability to evaluate programs, designs, etc. (See Lay of the Land and Larger Than Life).
Students are given an artifact, such as a program or design. The artifact proposes to be the solution to a problem, but while generally correct, the instructor has purposely introduced flaws into the program, design, or whatever. The artifact should be fairly large and should contain a number of flaws. Most of the flaws should be simple and obvious to most readers. There should be one or two deeper flaws.
Students are asked to find and correct the flaws. They can also be asked to discuss the nature of the flaws found and the reasons for their changes. Finally, they can be asked to discuss the overall structure of the artifact and draw inferences from it.
This pattern allows students to actively work with larger solutions than they can develop completely themselves. They benefit since finding flaws in their own work is a valuable skill. In programming, students see lexical, syntactic, and semantic errors. In design, they can see the effect of incorrect partitioning of responsibility.
It is important that the overall structure of the artifact be sound. If it is a program it should be well designed and written, with good choice of identifiers. If it is an analysis or design document, its overall structure should be sound with a clear map to the problem statement.
The best way to develop such an artifact is to start with an excellent solution to a problem and then doctor it by introducing flaws. There must be different kinds of flaws, but probably not structural flaws. This latter rule can be broken if the artifact is introduced later in the course rather than at the beginning, at a point at which structure is the main issue. When used as an Early Bird instance, however, concentrate on flaws of detail, rather than structure.
Follow up. Most such exercises cause the students to generate questions that can be a fruitful source for classroom discussion. If the instructor is careful to introduce certain flaws, the student can be led in a desired direction to further explorations.
A problem and a well designed and implemented artifact that you can manipulate to provide the necessary errors. These can come from industrial quality designs and professional books. They can also come from projects from previous years, provided that the instructor is willing to modify and improve the artifact so that it is truly of high quality prior to the introduction of flaws.
When introduced at the beginning of the course and introduces the key ideas of the studey then it is also an Early Bird
When the artifact is very large then it is also an instance of Larger Than Life
If the artifact is also illustrative of some important topic, then it is also an instance of Toy Box
When the artifact illustrates the overall topic of interest in the course it demonstrates Lay of the Land
If the repaired artifact is useful in some larger context it can also be a Tool Box instance.
This pattern has been used to teach
1. Beginning programming. Here the artifact is a program illustrating a number of syntactical constructs that have not yet been introduced in class. (It has been used as the first assignment.) The program can be large enough that its structure is not obvious. Two or three classes with several short methods each is about right. One part of the program might be more complex. Together with the driver, there should be three or so pages of code. The errors can be mostly syntactical and lexical, so that the compiler can find them. One or two semantic errors should also be introduced, so that the program does not perform as expected. More serious and perhaps for more advanced students is the failure to fulfill a precondition contract. Ten to fifteen errors is about right if most are easily caught.
Even a single class can be introduced that has a flawed public interface. Students can be asked to analyze the consequences of this in relation to the likely current and future use of the class.
2. Introduction to design. Here a problem is presented and a design for the solution. Six to ten major elements in the design is about the right scale. The design should have a few simple flaws, such as missing message paths or missing functionality within a class. Improper partitioning of responsibility in a small region of the design is relatively easy to introduce. One subsystem could be left out. If the design requires several documents, there might be an inconsistency between the documents. Five or six flaws is probably enough.
3. Some (Linda Rising) have used this pattern with very large artifacts -- large enough that they can't be understood by a single person at the level of the students and therefore require teamwork.
This must be carefully used if student honesty is an issue. It is easy for one student to point to the locations of errors in C++ programs, for example. One way to address this is to use large artifacts that require teamwork. Another is to ask questions concerning the structure as well as the errors. Finally, the students can be asked to examine the artifact before they are given the full set of questions that will be asked about it.
Some students are frustrated by such large artifacts. The instructor must be prepared to provide support and encouragement that the real world really is like that and that it is ok to initially (a) be frustrated and (b) lack knowledge.
Kyle Brown (the pattern shepherd) and the participants in the OOPSLA '98 Pedagogical Patterns Rewriting BOF were very helpful in improving the presentation of this pattern.
Pedagogical Pattern #32
(Version 1.2, October 1998)
Topics in a course are divided up into fragments and the fragments introduced in an order that facilitates student problem solving. Many of the fragments introduce a topic, but do not cover it in detail. Just enough detail is given initially so as to form a basic understanding that can be applied to problem solving. Additional cycles contain reinforcing fragments that go into more detail on the topic.
Any course in which there are a large number of concepts that must be mastered together.
This pattern can be used in several courses, primarily at the early stages of the curriculum. It can be used (at least) in programming courses, analysis and design courses, and special courses in object technology. A variation of this pattern is often used in the compiler construction course.
Many fields can only be mastered by individually mastering a large number of different techniques that must interact.
Large topics such as programming and design require many parts and much detail to master. Developing these in a sequential manner leaves the students without interesting exercises, as they have not seen enough of the breadth of the topic to do interesting things.
Students like to build things and they like to see how the pieces fit together. They get bored easily if instruction is repetitive and if the instructor spends too much time on one topic or a set of closely related topics. Students can also get bored if exercises are artificially contrived to illustrate arcane details.
Courses do not need to be organized like reference material.
Organize the course so as to introduce topics to students without covering them completely at first viewing so that a number of topics can be introduced early and then used. This can get students working on interesting problems earlier as they have more tools to use, though they have not, perhaps, mastered any of the tools. The instructor can then return to each topic in turn, perhaps repeatedly, giving more of the information needed to master them.
On each cycle of the spiral topics are covered in more depth and additional topics are included. The sequencing of the "fragments" is done with an eye to providing students with problem solving skills. Anthony's Mix New and Old suggests the important of mixing new material into what is already known.
The course cycles around to a given topic several times during the term, each time to a greater depth.
This pattern results in the topics of a course being more fine grained, with just enough of a larger topic introduced at each stage to permit problem solving with other tools/topics which are also, as yet, not completely covered. For example, "iteration" is a big topic. The "while loop" is a small topic, especially if initially introduced with only simple loop tests. Yet the while loop can be used effectively with other constructs to build meaningful programs before iteration is understood in all of its aspects.
To start, the instructor should extract a subset of the material covering several topics that interact. Only simple cases should be introduced at first. The instructor and class move quickly through the topics until an understanding of how the topics interact can be gained. Students then can work with the tool subset on problems. Then more of each of the original topics, with perhaps simple cases of new topics are introduced to deepen understanding of the topics and of their interactions. Students then work on a richer set of problems. This can be repeated as often as necessary.
Students will get a feel earlier for how the pieces fit together. A potential negative consequence for some students, at least, is that some of their questions (What if...?) may need to be deferred (see Test Tube).
The instructor needs a plan, showing the order in which the topics will be introduced and what will be deferred to later cycles.
The instructor must extract subsets of each of the many topics in which the tools introduced can work together in problem solving. Several, increasingly large subsets, must be designed. Problems using most of the features of each subset need to be designed. One way to design the subsets is to start with the problems and extract a minimal set of tools necessary to solve that problem and similar problems. The next larger subset can often be designed by thinking about how the original problem could be expanded and its solution generalized.
Early Bird can get you started on the first cycle.
Test Tube can be used to avoid getting bogged down.
Toy Box can be used to provide a sequence of increasingly difficult exercises.
Lay of the Land and Larger Than Life can be used to provide an overall vision.
Fixer Upper can be used to introduce new material for each cycle.
This pattern can make Early Bird and Lay of the Land work well together.
Dana Anthony has several patterns that inform this one. In particular, Mix New and Old, Seven Parts, Example Lasts One Week, and Visible Checklist can be used to design each cycle around the Spiral.
This pattern can be used to teach low level programming structure. For example integer data, assignment statements and simple forms of if and while can be introduced. Problem solving using these topics only can be introduced allowing students to solve simple programming problems. In the second cycle, more can be discussed on each of these topics (else clauses, infinite loops,...).
In analysis and design, simple analysis techniques and tools can be introduced (simple use-case) and then the class can move to simple designs (CRC cards). Students can thus get a feel for the whole process, solving simple problems. The second cycle can introduce simple features of more sophisticated tools as well as somewhat more complex problems.
In object technology courses, simple inheritance can be introduced and used before polymorphism (dynamic binding) is discussed.
This pattern cannot be used in a small way. A commitment needs to be made to it. If this is not possible or desirable, avoid it entirely.
The book Ten Statement Fortran Plus Fortran IV by Michael Kennedy took a spiral approach.
Karel the Robot, by Richard Pattis (Wiley, 1981) was a first cycle in a Spiral approach to Pascal. Its successor, Karel++, by Bergin, Stehlik, Roberts, and Pattis (Wiley, 1997) tries to do the same for an object-oriented language like C++ or Java.
Dana Anthony's patterns were presented in PLoP '95.
Pedagogical Pattern #33
(Version 1.2, October 1998)
Students are asked to create an artifact such as a program or design that contains a specific error. Use of this pattern explicitly teaches students how to recognize and fix errors. We ask the student to explicitly make certain errors and then examine the consequences.
This is very applicable to the early stages of learning programming. Syntax and semantic errors are frequent and students need to become familiar with the messages produced by compilers and run-time systems and what they indicate about the program.
The pattern could also be used in an analysis or design course in which certain specific, but fairly common, errors are required to be part of the design. The instructor can provide a part of the design, which is flawed in some way, and the students are asked to complete the design without changing the instructor's part. (See the Fixer Upper pattern also.)
This pattern is often used in Database and Operating Systems courses where the students are asked to explore the conditions leading to deadlock, by specifically causing it. Similarly, in learning concurrent programming, students are often asked to write programs in which race conditions between processes lead to the corruption of data.
Students, like professionals, make errors. Professionals generally know what the indications of an error are, but students do not.
We usually help students avoid errors, but they occur anyway. Students should have a way to explore the effects of errors so that they can recognize them by their effects.
Students are asked to produce an artifact with certain specific errors (usually a single error), and the effect of the error is then explored.
For example, students are given an assignment in which they are instructed to create and run a program with certain specific errors. They are then asked to comment on the diagnostics produced and/or why no diagnostics were produced for the error.
Students become more familiar with errors and how to correct them. Having seen specific errors, they can learn to avoid making them in the first place.
The instructor should carefully prepare exercises using this pattern and be sure to do the exercise before the class does, so that unanticipated occurrences can be prepared for and explanations of precisely what happened can be provided later.
Follow up. It is important that the students get a chance to discuss interesting things that occur while making these errors.
One especially useful technique is to ask students to make errors that, when they occur accidentally, are especially hard to diagnose when made accidentally. One example of this is errors made in C++ template instantiations.
The instructor simply needs knowledge of common errors.
In Fixer Upper the instructor makes the errors and the students correct them.
In Test Tube we ask for explorations. Here we ask for explorations of specific errors.
Several were given under Applicability, above. In addition, this pattern can be used effectively to teach students about pointers in languages like C or C++, by having them make all of the common pointer errors purposely. This particular use is somewhat dangerous on computers that have memory mapped i/o and unprotected operating systems. Both syntax and semantic errors can easily be explored using this pattern.
One exercise from an old book [Teague] was to write a program that produced every diagnostic mentioned in the manuals for a given (Fortran) compiler. This is, not surprisingly, very difficult to do. Impossible, for some compilers, as the documentation and the compiler are not completely parallel.
This pattern can be over used. It is best used early and in response to student questions.
Computing Problems for Fortran Solution, Robert Teague, Canfield Press, 1972.
Pedagogical Pattern #34
(Version 1.2, October 1998)
The course is organized so that the most important topics are taught first. Teach the most important material, the "big ideas," first (and often). When this seems impossible, teach the most important material as early as possible.
This has very wide applicability to almost every domain. If design is more important than programming, then find a way to do design as early as you can. If functions are more important than if-statements in programming then do them first. If objects are more important than functions, then do them first.
Students need to see where they are headed. They need to see that detail presented early in the course will relate to important ideas.
Students often remember best what they learn first. This can be both positive and negative, of course. Important (big) ideas can be introduced early, even if they can't get complete treatment immediately.
A course is mined for its most important ideas. These ideas become the fundamental organizational principle of the course. The ideas, and especially their relationships are introduced at the beginning of the course and are returned to repeatedly throughout the course.
Here we order class topics in order of importance and find ways to teach the most important ideas early.
The most important things in a course or curriculum receive more focus from the instructor and the students. Students can be made more aware of what is paramount.
Implementation is difficult. Often only simple aspects of an important idea can be introduced early. Sometimes it is enough to give important terms and general ideas. Some "big" ideas are thought of as advanced. It is difficult to introduce some of these early. Hard thought and preparation are needed in curricular design. Sometimes a really big, but difficult, concept can be introduced incompletely. Then as other material that relates to it is covered, the relationship to the big idea is carefully explored.
Professors need to be able to analyze deeply what are the consequences of developing material in a particular order. It is often helpful here to have a forum in which ideas can be discussed and refined. It is also often necessary to develop your own materials, which requires time and effort.
Time and deep thought are clearly required. Discussion groups with other educators who share similar ideas about the most important concepts in a domain are very helpful.
It may be necessary to Spiral to give some needed background on the important topics.
A Lay of the Land example can be used to show the students an example of a big idea in action. If there are many important ideas it can be Larger Than Life.
A Fixer Upper can be a good way to get started. It must emphasize the big idea of course.
If the idea is complex, use a Toy Box example to introduce it.
Interrelated ideas can often lead to components of a Tool Box.
Note: This pattern is actually recursive, as patterns themselves are a really big idea.
Teaching objects first (or at least early). Teaching design first. Teaching concurrency first in operating systems. Teaching user requirements first in Database. Teach recursion before loops. Of course, these are my definitions of what is most important. You may disagree, but then it is your course, so discover and implement your own "firsts."
The book Karel the Robot, by Richard Pattis was designed with this pattern in mind as a way of teaching procedural programming (procedures first). Its successor, Karel++, attempts to do the same with Objects (classes first).
It may be a mistake to try to use this pattern with material that has clear prerequisite ideas to the important ideas. This would be especially true if the relationship between the prerequisite idea and the big idea is especially subtle or if the prerequisites are especially difficult to master. Then again a clever use of Toy Box or Lay of the Land might let you do what seems difficult in presenting topics early.
Karel the Robot, Richard Pattis, Wiley, 1981
Karel++, Joseph Bergin, Mark Stehlik, James Roberts, Richard Pattis, Wiley, 1997.
Pedagogical Pattern #35
(Version 1.2, October 1998)
The intent of this pattern is to give the students broad historical and technological knowledge of the field by letting them "play" with illustrative pedagogical tools.
The pattern can be used in several courses and at several levels. It can be used very early in programming courses and in teaching upper level courses as well.
Students must deal with a great amount of detail. Sometimes it obscures how the detail is to be used.
Many applications of computer science are very complex and outside the skill level of novices to absorb completely.
While we are teaching programming, it is nice to let the students program with things that will teach them some simple ideas from courses that they will encounter later in the curriculum.
Students have to program with "something." Often it is just integers and floats at the beginning. It could be things more exciting to them and which teach them on a variety of levels simultaneously.
Students examine and interact with specially written, scaled down, examples of realistic applications such as word processors, database management systems, and spreadsheets. These applications are reduced down to their simplest form possible.
Student exercises are chosen to give the students a rich set of experiences about what can be done and what is important in computer science. These exercises are supported by a library of instructor provided materials that make learning fun.
Students are given a library of classes that can be used to implement some complex functionality. These are the building blocks. They then use them to build some artifact. Instead of programming with integers and arrays, they program instead with logic gates, for example.
The instructor distributes a class library that implements the basics of some functionality. The students may either use this unchanged or extend it and use the extended version to build some project. Care must be taken that the hierarchy is soundly built, demonstrating excellent techniques, and excellent structure.
In object oriented programming courses this is especially useful, as classes provided by the instructor can and should be used by students in any case. These can be carefully chosen to emulate larger systems.
This pattern allows students to actively work with larger programs than they can develop completely themselves. If the tools are chosen correctly, they can also gain breadth of understanding of the entire field. If the class hierarchy is well built it also serves as a good model for students building their own classes and hierarchies later, though the intent is not to teach OOP specifically.
Fairly rich hierarchies of classes implementing the tools must be supplied by the instructor. This is labor intensive, but resources can easily be shared.
This pattern can be used to provide examples for cycles around a Spiral.
A collection of these can be Larger Than Life, especially if closely interrelated.
A well chosen collection could also demonstrate Lay of the Land.
A set of classes that implement logic gates and circuits. Gates can be connected together to form circuits.
An assembly language simulator that lets students get familiar with goto/register programming without all the details of a real machine.
An extension to the above that shows some of the problems with concurrency. A set of classes that let students experiment easily with readers/writers conflicts, for example.
A simple game with complete information that plays against the user but learns from its mistakes.
A simple spreadsheet like program. The program can store "programs" in cells using the simple assembly language of earlier "toys".
A set of classes implementing a simple relational database that can be queried with a simple language.
Some of these things are complex, but with appropriate scaffolding, even beginning students can use and extend the tools appropriately.
Decker & Hirchfield's Analytical Engine is a good use of this pattern.
This requires a fairly long lead time and a lot of effort on the part of instructors, creating and finding materials. Don't try to use this pattern without commitment of time and resources.
The Analytical Engine : An Introduction to Computer Science Using the Internet, Rick Decker, Stuart Hirshfield, PWS, 1998
Pedagogical Pattern #36
(Version 1.2, October 1998)
The intent is to let the students build a tool kit in early courses for use in later courses. If well thought out and implemented, it can be a wonderful guide to reusable software. Students become apprentices in the same sense that young people once served as apprentices in medieval guilds. There they spent their early years building tools they would need if they were to achieve master status in the guild.
Students build things in early courses that will actually be used later in the same course and in later courses as well.
The pattern is used most heavily in the early programming courses, especially the data structures course. However, it can be added to as well as used in later courses such as database, AI, operating systems, compilers, and the like.
Students in later programming courses make use of knowledge from earlier courses, but in the past made little use of the actual programs built there.
Having a personal tool kit of reusable software components can be a wonderful help in a difficult project.
Building a tool kit stresses different, but important, skills.
Student exercises have multiple parts. One part of each exercise is to build a general tool that might be useful in other projects and to take some effort in its proper formulation for reuse. The design for reuse must be explicit and must be discussed by the students and commented on by the instructor. Groups of students can combine individual designs of the tools, discuss the relative merits of each and then build a common implementation that improves each of the individual designs.
Students gain skill in the early courses building reusable components. To the extent that they fail, the lessons are reinforced in the later courses when they need to rebuild parts of the tool kit for use in the projects of those course. Languages supporting reusability need to be used. Most of these languages are either object-oriented or functional. Scheme, C++, Eiffel, Java, Ada are good choices. There are a few others such as Modula 3, Beta, Oberon, CLOS, and Standard ML. Languages supporting genericity (templates) are especially useful.
Instructors can provide some tools (data structures and algorithms) in the form of class hierarchies or other libraries. Students complement this collection. Time should be spent by students and instructor evaluating student built tools for correctness, of course, but also for the potential for reusability. Instructors in later courses must be aware that students have these personal tool kits and should use exercises and projects that exploit the tool kits and permit their extension.
Coordination with later courses is an important element of this pattern.
Thought needs to be given in the design of the early courses as to what tools are broadly useful, but especially which tools will necessarily be useful in later courses. Thought should also be given to platform independence of the tools. The instructor needs a plan and must be able to provide implementations of those tools that the students will need, but will not build themselves. For example, the instructor can give a singly linked list and have students build a doubly linked list. Both would be included in the toolkit.
Fixer Upper can be used by the instructor to provide partially flawed tools for the students to comment on and repair.
Tools can be built as part of each cycle of a Spiral.
Kernighan & Plauger's Software Tools books were a good use of this pattern. This book should probably be read by anyone who wants to implement this pattern. It shows how a high degree of reusability can be achieved with extremely simple tools.
Many data structures, with only slight modification, could be taken as early examples of this pattern.
Lisp, ML, and Scheme depend heavily on libraries of functions. These can be built in early courses and used later.
This pattern is probably not for use in theoretical or "concept" courses.
Software Tools in Pascal, Brian Kernighan, P.J. Plauger, Addison Wesley, 1981
Pedagogical Pattern #50
(Version 1.2, October 1998)
Lay of the Land
Students are given some early experience in examining a large artifact, beyond their ability to produce, with the intent of showing them the complexity of the field they are about to study.
This has very wide applicability to almost every domain. It is especially useful in teaching topics with a lot of parts that must fit together in certain ways. Teaching programming is one example. Teaching design methodology is another.
Teaching is often incremental, with topics introduced one after the other.
Students need to see the big picture too, as well as the detail.
Early on, they can produce only simple artifacts, but they can examine, if only in a superficial way, a complex artifact.
Seeing the big picture can give them motivation for the study of the parts as they have an idea of how they might be used.
Students are given a large artifact to examine early in the course. They can see what it is that they are supposed to be about in that course and what kinds of things they will be expected to master.
The artifact has about the complexity of the thing you would like them to be able to produce at its end. Time is spent examining the parts and their interactions. Time can be spent on trade-offs inherent in the design or not, but the notion of design tradeoffs should be mentioned at least. The artifact should include most of the elements that are the proper study for that course. It is good if the artifact has some subtle points. If questions arise initially on these points they may be deferred, but it may mean you have better students than you think. The artifact can be returned to throughout the course and the subtle points revealed and discussed.
Students get to see a target for their study. They also have a model on which they can base their own work.
The artifact must be prepared ahead of time. Student projects from prior years are a good source, though they may need to be modified somewhat to emphasize points the instructor believes most important. If these are large, a good way to transmit them to students is via the Internet, especially the Web. This way other educators can use them also.
Good solutions to larger projects are needed. These must exhibit excellent structure and style, as we are hoping that the structure and style will be emulated by the students.
One of these could easily be Larger Than Life.
A Spiral could be used to examine parts of the artifact on successive cycles. This is especially true if the parts are tightly coupled.
The artifact could also be a Fixer Upper.
If chosen carefully, it is also an Early Bird.
Test Tube can be used to let the students answer their own questions about the artifact.
A large Object-Oriented program with a few classes interacting in an interesting way is a good choice in a first programming course using an object-oriented language. A complete design with many documents can be used in a systems design course. A complex database design with entity relationship charts and tables can be used in a database design course.
Some compiler course instructors give the students a complete compiler for one language and then ask them to provided a compiler for another over the course of the term.
Pedagogical Pattern #52
(Version 1.0, October 1998)
Students can answer their own "What if " programming questions with access to a computer. Sometimes this is quicker and more effective than formal documentation. Students can also explore the undefined parts of some computer languages.
Beginning programming courses.
Students can take up a large amount of class time asking questions at a very low level of detail. They can also become very frustrated if they cannot find sufficiently detailed documentation to answer their questions.
Give the students several exercises in which they are asked to write small programs to get the computer to answer simple questions of the form "What happens if ". These exercises should be frequent enough that students get in the habit if probing the machine for what it does, rather than the documentation.
Some languages are underdefined. In these languages, the instructor will need to point out a few places where there are no rules. In particular, the order of evaluation of parameters in C++ is not defined in the standard. Therefore, the most that a program will tell you is what is the effect using a compiler at hand. It can't give you a general rule as there is none. Students need to be aware of these situations so that they can program defensively and now draw misleading conclusions.
Student questions can be a good source for exercises of this kind. The instructor can take a student question and turn it into a very short term (overnight) exercise. If a laboratory is available, students can immediately test out hypotheses about how things operate.
This can be used in conjunction with Fixer Upper.
If the purpose of the exercise is to generate errors, then this is an instance of Mistake. This pattern is more general than Mistake, however.
This can be used effectively to make cycles around Spiral move quickly without getting bogged down in too much detail.
The meaning of for loops in C++ can be explored in a sequence of exercises in which the initialization, test, and "increment" portions of the loop are varied.
When a while loop exits (between executions of the body) and when it does not (as soon as the condition becomes true in the middle of the body) can be explored in exercises.
The difference between value and reference parameters and the meaning of const can be explored.
Pedagogical Pattern #53
(Version 1.0, October 1998)
Larger Than Life
Students of Object-Oriented programming and design can and should examine and use computing artifacts much earlier than they can design and build them themselves.
In courses other than computer science, students regularly work with texts and other artifacts far larger and more sophisticated than they could produce themselves. A literature or history course is a good example. The same occurs in sociology courses. These artifacts teach the student what is best in the field and should be emulated.
Students at all levels, from raw novices to quite experienced students.
Students cannot initially produce programs and other software development artifacts of any complexity. However they need to be introduced to the complexity of real systems. They can, in fact, examine and learn from programs and other artifacts far beyond their ability to produce. Much time is spent in class on quite low level details, yet students need to see the big picture.
If the student builds everything that they use, they will get a very stilted view of how real software is produced in the world. They are also unlikely to have a real appreciation for the complexity of real systems, or the requirements of software that will be used by people other than its author.
Give the students access to large programs and designs well before they have the ability to produce them. These artifacts can be used as the basis of exercises. Students can make small modifications to large programs and they can extend them in simple ways early on. They can also make corrections to flawed large programs if the flaws are of modest difficulty (see Fixer Upper).
These artifacts should generally be of high quality design, so that students will have a template to emulate in their own work. An exception is made if the goal of the exercise is to improve a large but poor design.
Unlike the days in which languages were simple and libraries non-existent, students today need to be able to use libraries written by others. These libraries are usually more complex than the students could create. They may also contain much code of generally low conceptual content, so that it isn't worth course time to develop them from scratch. Their design, however, may be of some interest.
Large computing artifacts of good design.
If the artifact requires repair then it is also a Fixer Upper.
If it stresses the big ideas and is given early it is an Early Bird.
If it is generally useful it is a Tool Box entry.
If the artifact covers most of the main concepts in a course it is also an instance of Lay of the Land.
The Standard Template Library of C++ is such an artifact. So is the AWT of Java. Design documentation for large systems are examples. Complete programs such as compilers and operating systems are also useful. One standard technique in a Compiler course is to give the students a complete compiler for one language at the beginning of the course. This artifact is then examined over the term and the students build a compiler for a different language.
In any object-oriented course, students will benefit from the use of libraries prepared by others, either instructor written, or perhaps standard libraries.
Linda Rising gives an example of a software design project that is both Larger Than Life and a good Lay of the Land. It has some features of a Fixer Upper as well.
Rising, "Removing the Emphasis on Coding in a Course on Software Engineering", SIGCSE BULLETIN, February 1989.
Pedagogical Pattern #
(Version 1.0, December, 1998)
Fill in the Blanks
Students can often learn a complex topic by building several small parts of a larger artifact. This aids both their reading and writing skills.
This pattern is intended for introductory programming courses that attempt to move students quickly to difficult material. It is probably possible to adapt this to design as well.
Students have a difficult time developing complex programs from scratch, but the programs that they can build early are usually quite boring.
Students should see how the work that they do fits into a larger context.
Students can learn to read programs earlier than they can learn to write them. But, they should not be permitted to be overly passive in their reading.
Prepare a very well designed program or part of a program and remove a few pieces of the code. Give the result to students with instructions to fill in the missing parts. The missing parts need to be well specified. It is also best if the result will be put to some use immediately so that students can see the effect of their work.
The overall design of the artifact must be excellent.
The missing pieces should be carefully selected so that students can deduce something about the missing parts from the supplied parts.
In some cases the missing parts can be carefully specified with pre and post conditions. In others, the specification step can be left to the students. They could even be created in class in a Student Design Sprint.
The missing pieces could require different kinds of skills to complete. Some missing parts might require little beyond basic syntactic knowledge, while some might require deep semantic analysis. If used repeatedly (as in a Spiral) the successive uses could require deeper analysis each time.
Any well designed artifact that can be modified will do.
In Fixer Upper, students repair a carefully broken artifact. Here they complete an artifact carefully left incomplete. The artifact can also be Larger Than Life, or an Early Bird or Lay of the Land.
A simple example is a class definition in a language like C++ or Java in which some of the method bodies have been omitted. Slightly more complex is one in which part of the interface itself has been left out.
Even simpler is to leave out a single line of code somewhere, though you must provide appropriate comments so that students don't need to guess where these blanks are.
An application could be provided that required certain library code (stack, queue, ) that the student must provide.
At an extreme end of the spectrum, a major component of a project could be left to the students.
Mail from Peter Henderson (SUNY Stony Brook) reminded me of this. He uses it extensively in CS I.
The above patterns work well together as indicated within each pattern. Actually these arose over many years of teaching. It is object-orientation, however, in which they find their greatest manifestation yet.
Back in the late 1970's when U.S. educators were moving from Fortran to Pascal we made a number of serious errors early on. Many of the books of the time were better as reference works than as texts for students. Most of the early books relegated functions to a very late chapter. Types weren't used especially well and ADT's were non-existent.
I remember what a revelation it was to find the book Karel the Robot, by Richard Pattis. Here were functions done first, not just early. Here was a very simple starter that showed the Lay of the Land of programming. It was simultaneously a Toy Box and the first cycle of a Spiral. Very powerful stuff, and very useful for both educators and students. The algorithms developed with Karel had direct impact on learning Pascal. For example, a robot searching for a beeper has exactly the same structure as a program searching a sentence for its period.
I fear we are making the same errors in moving from procedural programming to object-orientation. I've read papers lately, written by educators, who claim that the "received wisdom" is that object-orientation should be taught late, as an add on to procedural programming. This goes counter to the experience of professionals in the object-oriented world who have seen how much differently one must think to be successful in this new world. If you want to produce object-oriented developers, they should learn this first (Early Bird).
The field is complex and has many parts. These must be shown to fit together in comprehensible ways (Lay of the Land). The programs we build now are much larger and more complex than was true ten years ago. Students need to be introduced to this scale (Toy Box). Reuse is more important now (Tool Box). Languages are more complex (Test Tube, Mistake).
Software is built in teams, and maintenance is often the dominant cost. Programs are too big to be understood by individuals and they grow from a well-designed core (Larger than Life, Fixer Upper).
We are teaching new and better topics and tools than we did a few years ago. I believe that our methodology must change as well. When teaching Pascal, few relied on pre built libraries of code with which the students would interact, since most Pascal programs are built largely from scratch. Most C++ and Java programs are not built that way, however, so students need different experience than many of their instructors had. This implies that the instructor must be prepared, not only with knowledge and pedagogy, but with tools and libraries. It took me 25 years to know what I do about computer science. I expect my students to get there in less than a third of that time. Their experiences need to be very different from mine to make this possible.
In fact, object-orientation itself can provide these tools. Well designed classes are inherently reusable. They can be used to build toys which give the students both examples of object-orientation that they can emulate, but also tools to work with and extend. We must learn to use the tools to teach the tools. And we must match our pedagogy to the exciting new things that we are trying to teach.
One of the themes that run through all of these patterns is the requirement that the artifacts that we show students be of the highest quality. Programs must be beautiful as well as correct. Designs must be excellent. Our programming and diagramming style must be of the highest order. Students look up to professors for guidance and emulate what we do. It is occasionally ok to show students work in development, but they should also see the final products. Perhaps I should have written this as a pattern (Quality is Job One).
Another common theme here is that students need to get early practice in working with software development artifacts much larger than they are capable of producing themselves. This is very common in other fields as mentioned above. More to the point, engineering and architecture students work with large engineering and architecture artifacts long before anyone would dare let them build much of anything. This has multiple benefits, among which is the ability to show students the best of both historical and contemporary work in their field. It gives students something to strive for and something to emulate in their own work. A professor of architecture will come to class with more than just ideas. He or she will come with a corpus of work that the students will be asked to examine. Students will see the architectural drawings, and perhaps the engineering drawings as well. With luck, they may be able to visit one or more of the buildings of the architect. Computer science students need this same exposure to great works.
The reader interested in this work should also read the paper, Patterns for Classroom Education by Dana Lynne Goldblatt Anthony which was first presented at PLoP '95 and was published in Pattern Languages of Program Design 2, by Vlissides, Koplien, and Kerth, Addison Wesley, 1996. The above link is to an online version. Many of the patterns here and in Anthony's paper complement each other.