3.5 Describing the Meanings of Programs: Dynamic Semantics 147
3.5.2.5 Logical Pretest Loops
The denotational semantics of a logical pretest loop is deceptively simple.
To expedite the discussion, we assume that there are two other existing
mapping functions, Msl and Mb, that map statement lists and states to states
and Boolean expressions to Boolean values (or error), respectively. The
function is
Ml(while B do L, s) Δ= if Mb(B, s) == undef
then error
else if Mb(B, s) == false
then s
else if Msl(L, s) == error
then error
else Ml(while B do L, Msl(L, s))
The meaning of the loop is simply the value of the program variables after the
statements in the loop have been executed the prescribed number of times,
assuming there have been no errors. In essence, the loop has been converted
from iteration to recursion, where the recursion control is mathematically
defined by other recursive state mapping functions. Recursion is easier to
describe with mathematical rigor than iteration.
One significant observation at this point is that this definition, like actual
program loops, may compute nothing because of nontermination.
3.5.2.6 Evaluation
Objects and functions, such as those used in the earlier constructs, can be
defined for the other syntactic entities of programming languages. When
a complete system has been defined for a given language, it can be used
to determine the meaning of complete programs in that language. This
provides a framework for thinking about programming in a highly rigor-
ous way.
As stated previously, denotational semantics can be used as an aid to lan-
guage design. For example, statements for which the denotational semantic
description is complex and difficult may indicate to the designer that such
statements may also be difficult for language users to understand and that an
alternative design may be in order.
Because of the complexity of denotational descriptions, they are of little
use to language users. On the other hand, they provide an excellent way to
describe a language concisely.
Although the use of denotational semantics is normally attributed to Scott
and Strachey (1971), the general denotational approach to language description
can be traced to the nineteenth century (Frege, 1892).