I have started a series of articles on how programming languages are used. The first one is already published.
How a programmer interacts with a programming language in the effort to create a program is one aspect of a programming language design that, although implicit in the way the language is used, isn’t traditionally explicitly present in language design discussions.
The interaction model describes the conceptual model of the act of programming presented by the language. This concept is sometimes confused with the language implementation. We describe languages as interpreted or compiled, but this refers to how the language builds the program and not to how the programmer specifies the program. As implementation techniques have grown complex and varied, the two historically separated models of compilation and interpretation have been blurred. Now the implementation has little or no bearing on how the language is used. Given almost any language definition we can build an interpreter, a compiler or many things in between, but the way the programmer interacts with the language will not change (much).
Historically there hasn’t been much discussion on interaction models in programming language design. As far as I know, only during the standardization of Smalltalk these matters where discussed in depth, as in Allen Wirfs-Brock’s presentation A Declarative Model of Smalltalk Programs and equally-titled article proposing that Smalltalk changed its interaction model to allow code sharing between different implementations.
Wirfs-Brock describes two different models of specifying programs, declarative and imperative. I’ve chosen to call them descriptive and constructive to avoid overloaded terms.
A descriptive model, traditionally present in compiled languages, makes programming the process of assembling a series of declarations that when processed with a tool external to the language (a compiler) produce a program.
In contrast, a constructive model bases programming on changing through side-effects the state of the programming system. The interpreter or compiler is usually a part of the system too, and not explicitly used.
Programming language interaction should be an important, separate concept in programming language design. Many interesting discussions can arise from investigating programming language interaction models:
- The usual comparative strengths and weaknesses in each model, which can easily degrade into a flamewar.
- The implications each model has on the language implementation, related tools and programming practices.
The interaction model can also be a useful tool in characterizing and understanding programming languages. Each language supports a different model in different degrees, directing design decisions like
- the relation between code and executable,
- whether compilation (or interpretation) is an explicit or implicit process,
- the possibility of computation or side-effects during compilation.
Each programming language has embedded in it a particular narrative of not only how programming is to be done, but also what programming is and even what can be programmed.