The material in Programming Language Pragmatics can be used to teach a wide variety of courses in language design and implementation. Some of the options are shown in the figure below. For reference, see the table of contents.
Some chapters (2, 4, 5, 9, and 13) have a heavier emphasis than others on implementation issues. These can be reordered to a certain extent with respect to the more design-oriented chapters, but it is important that chapter 5 or its equivalent be covered before chapters 6, 7, or 8. Many students will already be familiar with some of the material in chapter 5, most likely from a course on computer organization. In this case the chapter can easily be skipped. Be warned, however, that later chapters assume an understanding of the assembly-level architecture of modern (i.e. RISC) microprocessors. Some students may also be familiar with some of the material in chapter 2, perhaps from a course on automata theory. Much of this chapter can then be read quickly, pausing perhaps to dwell on such practical issues as recovery from syntax errors.
For self-study, or for a full-year course, students should work through the entire book from start to finish. The one-semester course at the University of Rochester, for which the text was originally developed, also covers most of the book, but at a somewhat shallower level, leaving out material on bottom-up parsing (section 2.2.6), language theory (section 2.3), I/O (section 7.9), object file creation (sections 9.4-9.7), lambda calculus (section 11.2.4), predicate calculus (section 11.3.2), message passing (section 12.4), and code improvement (chapter 13).
In the typical undergraduate curriculum, the book is intended for the programming languages course. A typical syllabus would leave out sections 2.2-2.3 and chapters 4, 5, 9, and 13, and de-emphasize the implementation-oriented material in the remaining chapters, devoting the extra time to more careful examination of semantic issues and to alternative programming paradigms (e.g. the foundational material in chapter 11).
The book can also be used in an introductory compiler course. Here the typical syllabus would leave out sections 7.2.5 and 7.9, and chapters 11 and 12, and de-emphasize the design-oriented material in the remaining chapers, devoting the extra time to more careful examination of such topics as syntax error recovery (section 2.2.4), LR-family parsers (section 2.2.6), formal language theory (section 2.3), code generation (chapter 9), and code improvement (chapter 13).
For a school on the quarter system, one appealing option is offer an introductory one-quarter course and two optional follow-on courses. The introductory quarter might cover chapter 1; sections 2.1-2.2.3; chapters 3, 6, and 7; and sections 8.1-8.4. A language-oriented follow-on quarter might cover sections 8.5-8.6; chapters 10-12, and possibly supplementary material on formal semantics, type systems, or other related topics. A compiler-oriented follow-on quarter might cover sections 2.2.4-2.3; chapters 4, 5 (if necessary), 9, and 13; and possibly supplementary material on automatic code generation, aggressive code improvement, programming tools, etc. One possible objection to this organization is that it leaves object orientation and functional and logic programming out of the introductory quarter. An alternative (not shown in the figure) would be to start with a broader and more exclusively design-oriented view, moving sections 1.4-1.6 and 2.2.1-2.2.3 into the compiler-oriented quarter, de-emphasizing the implementation-oriented material in chapters 6-8, and adding sections 10.1-10.4, section 10.6, and the nonfoundational material in chapter 11.
Back to the book home page