Никлаус Вирт  в  России
Niklaus Wirth  in  Russia
Главная страница  /  Лекция в МГУ БОЛЬШОЕ ТУРНЕ  Н. ВИРТА

Teaching Principles! Which Principles?

Juerg Gutknecht, ETH Zurich
Moscow, September 19, 2005


This is a short essay on the topic of teaching software construction to students of computer science on a University level. We advocate an approach that neither takes the bait of glorifying the features of a certain programming language (however attractive they may be) nor looks down to reality from a formalistic or methodological podium. Instead, we suggest software construction to be taught on the basis of a well-chosen set of generic principles.


With the emancipation of computer science as a discipline to be taught at Universities and Polytechnics, and with the growing diversity of academic computer science curricula, the questions of profile, соntents and approach arise. When browsing the shelves of any bookstore that sells computer science literature, we soon recognize the premature state of the still young constructive science of computing. In their large majority, textbooks fall in one of two categories

  • Voluminous and rather accidental 1000+ page accumulations of a choice of recipes based on a more or less tricky application of specific features of some specific product
  • Promotions of a certain methodology as a cure all, often driven by its own momentum and adding one more layer to the problem set, as it is vividly put in metaphoric form in Tony Hoare's famous Turing Award lecture "The Emperor's Old Clothes"

Obviously, none of the two profiles qualifies for a serious academic education, mainly because the major concern in both cases is imposing a certain tool or methodology on the students, thereby putting on a symbolic corset and narrowing down the minds instead of opening them up. Quoting philosopher and "oracle of the electronic age" Marshall McLuhan: "We make our tools; then our tools make us".

If we address future computer scientists, we should much rather focus our teaching on the generic competence of making tools in contrast to the competence of knowing, using and mastering tools. Our educational efforts should be guided by the Chinese proverb "Give a man a fish and you feed him for a day. Teach a man to fish and you feed him for a lifetime."

So, good advice is urgently needed. My personal solution is teaching generic principles, where a generic principle is an archetype of a principle that distinguishes itself by the absence of inessential artefacts. Generic principles provide deep insight into intrinsic aspects, leave ample room for generalization and encourage creative and unexpected applications. Put differently, generic principles teach the art of abstraction.

It is worth noting that any coherent set of generic principles describing a discipline represents a design of the discipline on a meta-level. For example, the collection of generic principles discussed in the next section represents my personal design of the discipline of software construction. It is the quintessence of a 35+ years of experience in the field. With a view to emphasize the overall choice of principles, we leave it at an enumeration of the principles, augmented by a very short elaboration on each principle in note form.

The Generic Principles

  • Principle 1. Small-Scale Programming vs. Large-Scale Programming. The discipline of programming splits up into two methodologically very different sub-disciplines: Small-scale programming and large-scale programming. While small-scale programming is primarily concerned with programming of algorithms in the classical sense, the main topics of large-scale programming are global runtime structure, interoperability and orchestration. Advanced programming languages implicitly cover both sub-disciplines, with the result of an unfortunate blurring of concepts. However, separate frameworks for large-scale programming exist.
  • Principle 2. Programming by Stepwise Refinement (Small-Scale). The development of an algorithm is simplified considerabiy when divided in phases of successive refinements. Actions are typicaily specified merely by their name and parameters at an early stage of the development and refined in terms of a procedure including a local state space at a later stage. Recursion integrates naturally with this process.
  • Principle 3. From Specifications to Machine Programs (Small-Scale). The abitity of proving program properties with mathematical rigor is indispensable in any safety-critical scenario. The preferred approach to this goal is the use of a highly architecture-independent form for the specification of the algorithm and for the required proofs, and then to use an automated compiler for mapping the specification onto a given architecture, under invariance of the relevant properties. Assertions, invariants and non-determinism are powerful concepts in this field.
  • Principle 4. Separation of Interface and Implementation (Large-Scale). The notion of interface is of paramount importance in system design. The use of an explicit (and preferably thin) interface between a servant object and its clients is the key to reducing dependencies, with two beneficial consequences: The implementation of a servant object (a) can be exchanged at any time without compromising the system's integrity and (b) is fully protected against erroneous or malicious corruption. Another substantial benefit of an interface-aware design is the fact that clients may ignore all but the required facets of a servant object. Unfortunately, interfaces in current languages come as method tables only. Generalized forms such as dialog protocols and XML schemata would substantially enhance the power of the interface concept.
  • Principle 5. Event Control as a Reactive Runtime Model (Large-Scale). This is a well known runtime model or "design pattern" based on "inverse programming". Participating objects subscribe to the set of events they are interested in. On occurrence of an event, each of its subscribers gets notified by some "built-in" controller and thereby gets a chance to handle the event property. This model has regained popularity in some specific contexts, notably in graphical user interface programs (GUI), browsers and component frameworks for the purposes of activating commands and scripts ("on-click" events) and for "wiring" components (event --> reaction wire). One of the main benefits of the event control model is a strict and clean separation of the event detection logic (the controller) and the event handling logic (custom objects). In principle, it is possible to deploy a highly customizable system consisting of a sophisticated closed controller implemented in machine language plus a compiler for any suitable application-specific scripting language. Another completely different application domain for the scheme of event control is hot-pluggable system components such as device drivers.
  • Principle 6. Unification of Objects and Activities (Large-Scale). The metaphor of object-oriented programming features a multitude of qualities, among them conceptual support for (a) separation of concerns via encapsutation and (b) abstract treatment of objects via late binding of method implementations. Amazingly enough and in contrary to the original object-oriented language Simula-67, objects in current programming languages are "passive" and "remote controlled" by concept in the sense that they merely react on method calls issued by some external thread of control. A unified and more advanced computing model includes "active objects" that show some intrinsic behaviour in form of one or more encapsulated activities (think of a watch) and interoperate with each other via "stateful" dialogs (think of negotiating agents). Notice that the active object model in a very precise sense is the exact dual to the scheme of event control.
  • Principle 7. Introspection for the Support of Components (Large-Scale). Component systems distinguish themselves primarily by the existence of а builder tool that provides the functional support for assembling prefabricated and precompiled software components. Therefore, building is an additional phase between compilation and runtime that obviously depends on the availability of a universal mechanism called introspection for inspecting the properties of the precompiled constituents. In advanced component systems, the phases of development and building are completely decoupled, and the builder cannot count on any knowledge of the programming language and compiler used for the implementation of the different components involved in a composition. The only viable concept of introspection in such an advanced component system is a standardized mechanism of self-reflection built into each participating component.


The primary goal of any academic education for future computer scientists be competence in designing and implementing systems and in particular tools. We recommend an approach that is based on teaching a well-designed set of generic principles, illustrating both the art of abstraction and the "golden rule" of system design that could be paraphrased as follows: "Unify concepts that differ merely in inessential details and separate concepts that resemble each other merely in inessential details."

In concluding we notice that we do not advise the unchanged use of the method of teaching generic principles for non-computer science students. An approach on a more "literal" level may be sufficient and more effective in the cases of an audience consisting of "applied" computer programmers and of computer users respectively.


O  (13 сентября)  С.-Петербург
B  (19 сентября)  Москва
E  (26 сентября)  Нижний Новгород
R  (29 сентября)  Екатеринбург
O  (2 октября)      Новосибирск
N  (5 октября)      Томск

Информационные ресурсы:

Книги Вирта: