Daniel P. Friedman William E. Byrd Oleg Kiselyov
Drawings by Duane Bibby
To Mary, Sarah, Rachel, Shannon and Rob, and to the memory of Brian.
To Mom, Dad, Brian, Mary, and Renzhong.
(Preface ix)
((l. Playthings) 2)
((2. Teaching Old Toys New Tricks) 16)
((3. Seeing Old Friends in New Ways) 26)
((4. Members Only) 46)
((5. Double Your Fun) ((5. 60)
((6. The Fun Never Ends ...) 76)
((7. A Bit Too Much) 86)
((8. Just a Bit More) 108)
((9. Under the Hood) 130)
((10. Thin Ice) 144)
(Connecting the Wires 158)
(Welcome to the Club 162)
(Index 164))
The goal of this book is to show the beauty of relational programming. We believe that it is
natural to extend functional programming to relational programming. We demonstrate this by
extending Scheme with a few new constructs, thereby combining the benefits of both styles.
This extension also captures the essence of Prolog, the most well-known logic programming
language.
Our main assumption is that you understand the first eight chapters of The Little Schemer'.
The only true requirement, however, is that you understand functions as values. That is, a
function can be both an argument to and the value of a function call. Furthermore, you should
know that functions remember the context in which they were created. And that's it we assume
no further knowledge of mathematics or logic. Readers of the appendix Connecting the Wires,
however, must also have a rudimentary knowledge of Scheme macros at the level of let, and,
and cond.
In order to do relational programming, we need only two constants: #s and #u, and only three
operators: , fresh, and conde. These are introduced in the first chapter and are the only
operators used until chapter 6. The additional operators we introduce are variants of these three.
In order to keep this extension simple, we mimicked existing Scheme syntax. Thus, #s and #u
are reminiscent of the Boolean constants: #t and #f; fresh expressions resemble lambda
expressions; and conde expressions are syntactically like cond expressions.
We use a few notational conventions throughout the text primarily changes in font for
different classes of symbols. Lexical variables are in italics, forms are in boldface, data are in
sans serif, and lists are wrapped by boldfaced parentheses `O'. A relation, a function that
returns a goal as its value, ends its name with a superscript `o' (e.g., car° and nullo). We also
use a superscript with our interface to Scheme, run, which is fully explained in the first chapter.
We have taken certain liberties with punctuation to increase clarity, such as frequently omitting
a question mark when a question ends with a special symbol. We do this to avoid confusion
with function names that might end with a question mark.
In chapters 7 and 8 we define arithmetic operators as relations. The +° relation can not only
add but also subtract; *° can not only multiply but also factor numbers; and logo can not only
find the logarithm given a number and a base but also find the base given a logarithm and a
number. Just as we can define the subtraction relation from the addition relation, we can define
the exponentiation relation from the logarithm relation.
In general, given (*° x y z) we can specify what we know about these numbers (their values,
whether they are odd or even, etc.) and ask *° to find the unspecified values. We don't specify
how to accomplish the task: rather, we describe what we want in the result.
This book would not have been possible without earlier work on implementing and using
logic systems with Matthias Felleisen, Anurag Mendhekar, Jon Rossie, Michael Levin, Steve
Ganz, and Venkatesh Choppella. Steve showed how to partition Prolog's named relations into
unnamed functions, while Venkatesh helped characterize the types in this early logic system.
We thank them for their effort during this developmental stage.
There are many others we wish to thank. Mitch Wand struggled through an early draft and
spent several days in Bloomington clarifying the semantics of the language, which led to the
elimination of superfluous language forms. We also appreciate Kent Dybvig's and Yevgeniy
Makarov's comments on the first few chapters of an early draft and Amr Sabry's Haskell
implementation of the language.
We gratefully acknowledge Abdulaziz Ghuloum's insistence that we remove some abstract
material from the introductory chapter. In addition, Aziz's suggestions significantly clarified
the run interface. Also incredibly helpful were the detailed criticisms of Chung-chieh Shan,
Erik Hilsdale, John Small, Ronald Garcia, Phill Wolf, and Jos Koot. We are especially grateful
to Chung-chieh for Connecting the Wires so masterfully in the final implementation.
We thank David Mack and Kyle Blocher for teaching this material to students in our
undergraduate programming languages course and for making observations that led to many
improvements to this book. We also thank those students who not only learned from the
material but helped us to clarify its presentation.
There are several people we wish to thank for contributions not directly related to the ideas
in the book. We would be remiss if we did not acknowledge Dorai Sitaram's incredibly clever
Scheme typesetting program, SLAT. We are grateful for Matthias Felleisen's typesetting
macros (created for The Little Schemer), and for Oscar Waddell's implementation of a tool that
selectively expands Scheme macros. Also, we thank Shriram Krishnamurthi for reminding us
of a promise we made that the food would be vegetarian in the next little book. Finally, we
thank Bob Prior, our editor, for his encouragement and enthusiasm for this effort.
Food appears in examples throughout the book for two reasons. First, food is easier to
visualize than abstract symbols: we hope the food imagery helps you to better understand the
examples and concepts. Second, we want to provide a little distraction. We know how
frustrating the subject matter can be, thus these culinary diversions are for whetting your
appetite. As such, we hope that thinking about food will cause you to stop reading and have a
bite.
You are now ready to start. Good luck! We hope you enjoy the book.
Bon appetit!
Daniel P. Friedman
William E. Byrd
Bloomington, Indiana