An undergraduate compilers course poses significant challenges to students, in both the conceptual richness of the major components and in the programming effort necessary to implement them. In this paper, I argue that a related architecture, the interpreter, serves as an effective conceptual framework in which to teach some of the later stages of the compiler pipeline. This framework can serve both to unify some of the major concepts that are taught in a typical undergraduate course and to structure the implementation of a semester-long compiler project.
Several undergraduate-level texts on programming language theory make the formal connection between a language's type system and its concrete semantics explicit (for example, Harper @cite_2 ). The correspondence between an interpreter and a type-checker is an easy consequence of this.
@cite_2
1760139041 2084788336 1963705166 2034373223
Types are the central organizing principle of the theory of programming languages. In this innovative book, Professor Robert Harper offers a fresh perspective on the fundamentals of these languages through the use of type theory. Whereas most textbooks on the subject emphasize taxonomy, Harper instead emphasizes genetics, examining the building blocks from which all programming languages are constructed. Language features are manifestations of type structure. The syntax of a language is governed by the constructs that define its types, and its semantics is determined by the interactions among those constructs. The soundness of a language design - the absence of ill-defined programs - follows naturally. Professor Harper's presentation is simultaneously rigorous and intuitive, relying on only elementary mathematics. The framework he outlines scales easily to a rich variety of language concepts and is directly applicable to their implementation. The result is a lucid introduction to programming theory that is both accessible and practical. Part 1 Introduction: model programming languages lambda notation equations, reduction and semantics types and type systems notation and mathematical conventions set-theoretic background syntax and semantics induction. Part 2 The language PCF: syntax of PCF PCF programmes and their semantics PCF reduction and symbolic interpreters PCF programming examples, expressive power and limitations variations and extensions of PCF. Part 3 Universal algebra and algebraic data types: preview of algebraic specification algebras, signatures and terms equations, soundness and completeness homomorphisms and initiality algebraic data types rewrite systems. Part 4 Simply-typed lambda calculus: types terms proof systems Henkin models, soundness and completeness. Part 5 Models of typed lambda calculus: domain-theoretic models and fixed points fixed-point induction computational adequacy and full abstraction recursion-theoretic models partial equivalence relations and recursion. Part 6 Imperative programmes: while programmes operational semantics denotational semantics before-after assertions about while programmes semantics of additional programme constructs. Part 7 Categories and recursive types: Cartesian closed categories Kripke lambda models and functor categories domain models of recursive types. Part 8 Logical relations: introduction to logical relations logical relations over applicative structures proof-theoretic results partial surjections and specific models representation independence generalizations of logical relations. Part 9 Polymorphism and modularity: predicative polymorphic calculus impredicative polymorphism data abstraction and existential types general products, sums and programme modules. Part 10 subtyping and related concepts: simply typed lambda calculus with subtyping records, semantic models of subtyping recursive types and a record model of objects polymorphism with subtype constraints. Part 11 Type inference: introduction to type inference type inference for lambda xxx with type variables type inference with polymorphic declarations. Starting from a denotational semantics of the eager untyped lambda-calculus with explicit runtime errors, the standard collecting semantics is defined as specifying the strongest program properties. By a first abstraction, a new sound type collecting semantics is derived in compositional fix-point form. Then by successive (semi-dual) Galois connection based abstractions, type systems and or type inference algorithms are designed as abstract semantics or abstract interpreters approximating the type collecting semantics. This leads to a hierarchy of type systems, which is part of the lattice of abstract interpretations of the untyped lambda-calculus. This hierarchy includes two new � la Church Curry polytype systems. Abstractions of this polytype semantics lead to classical Milner Mycroft and Damas Milner polymorphic type schemes, Church Curry monotypes and Hindley principal typing algorithm. This shows that types are abstract interpretations. We present a new approach to adding state and state-changing commands to a term language. As a formal semantics it can be seen as a generalization of predicate transformer semantics, but beyond that it brings additional opportunities for specifying and verifying programs. It is based on a construct called a phrase, which is a term of the form C r t, where C stands for a command and t stands for a term of any type. If R is boolean, C r R is closely related to the weakest precondition wp(C,R). The new theory draws together functional and imperative programming in a simple way. In particular, imperative procedures and functions are seen to be governed by the same laws as classical functions. We get new techniques for reasoning about programs, including the ability to dispense with logical variables and their attendant complexities. The theory covers both programming and specification languages, and supports unbounded demonic and angelic nondeterminacy in both commands and terms.