We exhibit a set of functions coded in Haskell that can be used as building blocks to construct a variety of interpreters for Lisp-like languages. The building blocks are joined merely through functional composition. Each building block contributes code to support a specific feature, such as numbers, continuations, functions calls, or nondeterminism. The result of composing some number of building blocks is a parser, an interpreter, and a printer that support exactly the expression forms and data types needed for the combined set of features, and no more.
The data structures are organized as pseudomonads, a generalization of monads that allows composition. Functional composition of the building blocks implies type composition of the relevant pseudomonads.
Our intent was that the Haskell type resolution system ought to be able to deduce the appropriate data types automatically. Unfortunately there is a deficiency in current Haskell implementations related to recursive data types: circularity must be reflected statically in the type definitions.
We circumvent this restriction by applying a purpose-built program simplifier that performs partial evaluation and a certain amount of program algebra. We construct a wide variety of interpreters in the style of Wadler by starting with the building blocks and a page of boiler-plate code, writing three lines of code (one to specify the building blocks and two to (redundantly) specify type compositions), and then applying the simplifier. The resulting code is acceptable Haskell code.
We have tested a dozen different interpreters with various combinations of features. In this paper we discuss the overall code structuring strategy, exhibit several building blocks, briefly describe the partial evaluator, and present a number of automatically generated interpreters.
[1]
John C. Reynolds,et al.
Definitional Interpreters for Higher-Order Programming Languages
,
1972,
ACM '72.
[2]
Gerald Jay Sussman,et al.
An Interpreter for Extended Lambda Calculus
,
1975
.
[3]
Gerald Jay Sussman,et al.
The Art of the Interpreter or, The Modularity Complex (Parts Zero, One, and Two)
,
1978
.
[4]
Guy L. Steele,et al.
Common Lisp the Language
,
1984
.
[5]
Richard C. Waters.
XP: A Common Lisp Pretty Printing System
,
1989
.
[6]
Philip Wadler,et al.
Theorems for free!
,
1989,
FPCA.
[7]
Jr. Guy L. Steele,et al.
Common LISP: the language (2nd ed.)
,
1990
.
[8]
Eric S. Raymond,et al.
The New Hacker's Dictionary
,
1991
.
[9]
Philip Wadler,et al.
Comprehending monads
,
1990,
Mathematical Structures in Computer Science.
[10]
Philip Wadler,et al.
Combining Monads
,
1992
.
[11]
Philip Wadler,et al.
The essence of functional programming
,
1992,
POPL '92.
[12]
Simon L. Peyton Jones,et al.
Report on the programming language Haskell: a non-strict, purely functional language version 1.2
,
1992,
SIGP.
[13]
Eric S. Raymond,et al.
The New Hacker's Dictionary, 2nd Ed.
,
1993
.
[14]
Mark P. Jones.
A system of constructor classes: overloading and implicit higher-order polymorphism
,
1993,
FPCA '93.
[15]
Simon L. Peyton Jones,et al.
Imperative functional programming
,
1993,
POPL '93.