Introduction
Motivation: Reasoning about Program Behaviors
A program is a way of describing the behavior of some kind of computational
process. Familiar computational behaviors include things like: performing an
arithmetic calculation, storing some data (perhaps a bitmap image or other data
structure) in the computer's memory, printing an output to the terminal, or
reading the user's keystrokes. Other behaviors describe the interactions that
occur when we decompose a larger computational process into smaller ones. For
instance, when a client exchanges messages with a server following some
communication protocol, or when a program module invokes a OS system call or a
function provided by another module. Still other behaviors, which are sometimes
not very desirable but still necessary to describe, have to do with the ways in
which a computational system might misbehave, for instance by halting, raising
an error, or going into an infinite loop. A computation might behave
nondeterministically or probabilistically.
Because there are so many different ways that a computational process might
behave, there are many different programming language features (and programming
languages!) that we use to describe them. A programming language semantics
gives a precise mathematical characterization of these behaviors so that
programmers can reason about what their programs do. Such semantics are useful
not only for programmers, who need to understand the language semantics to
predict what their code will do, they also inform programming language
implementors. A compiler should faithfully translate the behaviors of the source
semantics into behaviors of the target semantics, and tools like static
analyzers and debuggers should respect the abstractions provided by the
language. A language semantics is a
specification for the programs written in
that language.
To account for the rich variety of computational phenomena, programming
languages researchers have developed a host of mathematical tools and techniques
that can be used to define semantics. Earlier volumes in this series showed how
to define operational semantics for Imp and the Simply-Typed Lambda Calculus,
two prototypical programming languages with relatively simple computational
behaviors. This volume explores how to define semantics for the richer kinds of
behaviors described above.