Syllabus
Course Instructor Date/Time Place Overview

This course is an introduction to formal semantic methods for programming languages. The importance of seeking to define our computer languages in a formal way is clear. There are two informal ways to decribe a language, but both have major problems when it comes to using them as a definition of the language. The first is simply to decribe, usually through examples, how the language is meant to be used. This is essential when teaching the language, but is inadequate as a definition of the semantics of the language. The other way is to build a implementation of the language (either a compiler or an interpreter). The problem with this is that different implementations can have different results with the same program, depending on the platform used and the choices of the implementor. Formal methods are needed to define the language, and also to guide the implementor to a correct implementation. Without these methods, we are left with informal descriptions which can be ambiguous, or, worse, inconsistent. Just as we use BNF (plus context-sensitive additions) to define syntax formally, we need a method to define semantics just as formally.

That's where the problems start. Syntax, especially if it is context-free, merely needs a simple formal grammar system. Semantics, which has the job of describing state transitions and other dynamic events has to be much more complex. There are three main ways to express formal semantics. Although they are related, they are based on different formal systems; their mathematical foundations are different. Axiomatic semantics was developed by Hoare, and later Floyd to express state transitions through pre- and post-conditions on program state. Denotational semantics was developed by Scott and Strachey for expressing the same state transitions as operations on sets and functions. Lastly, and most recently, so-called large-step operational semantics was developed by Plotkin to express state transitions through logical relationships between the components of the transition. All three methods tie syntax to semantics formally, and that is their main goal. All three answer the question "What is the meaning of a piece of syntax?" (i.e. a source code program), and all three do it by breaking down a whole program into its components (i.e. statements. expressions, etc.) It is possible, by using the techniques inherent in each method, to prove facts about programs mathematically. This is an important side-effect of the methods. No longer do we have to execute a program on a real machine to check results; we can prove them formally by applying the semantics to the source code. This is why these methods are so important.