Years ago I was led to the Schemer books by some of
Steve Yegge's blog posts. It's been over two years since I've read
The Little Schemer, but I enjoyed it so much that I always planned to read the sequel,
The Seasoned Schemer. I recently made the time to do just that, along with working through another Schemer book,
The Reasoned Schemer, that's not so much a continuation of the other two Schemer books as it is a tangential book written in the same endearing style as the others. Daniel P. Friedman and Matthias Felleisen wrote
The Seasoned Schemer in the style of a Socratic dialogue, but in a much more whimsical way. A host of authors, including Daniel P. Friedman again, as well as William E. Byrd, Oleg Kiselyov, and Jason Hemann put together the questions, answers, and Scheme-based reasoning language used in
The Reasoned Schemer. The real question is, are these two books as good as the original?
| VS. | |
The Seasoned Schemer
Do you like learning about programming?
#t
Do you enjoy challenges?
#t
How about functional programming?
#t
And food and pictures of elephants?
Of course.
Then you probably enjoyed The Little Schemer, and you'll enjoy this book just as much. The Seasoned Schemer more or less follows the same format as The Little Schemer, and it more or less picks up where the latter book left off. What do I mean by more or less? Well, the first book leaned more toward asking questions of the reader that you could actually answer from following the line of questioning. Towards the end it became more of a dialog between two people while the reader was observing that dialog. The Seasoned Schemer definitely follows the later style of a question-answer dialogue that the reader is not so much participating in, but taking in and learning from instead.
This change of pace is not necessarily bad, though. It was just as entertaining and enlightening as before, and there were plenty of times where I sat there chuckling at the zany Q&As that were bouncing back and forth. Whenever there were questions about how to write functions or what was the result of executing functions, I attempted answering them, but there were long of stretches of dialogue that were meant more to be experienced than to be answered.
As for continuing on from The Little Schemer, the book does do that, and the authors assume the reader has read it in its entirety. However, they do remind the reader what the functions are that they defined in the first book so you don't have to go searching back to refresh your memory. They also relax the difficulty level through the first few chapters instead of continuing to ratchet it up from the high level it was left at in The Little Schemer. That's a good thing, because things were getting pretty mind-bending towards the end of the first book, and it was nice to ease back into things before getting crazy-weird again, as things do when you're learning how to implement and interpret the functions you're learning about in the language that said functions are already defined in.
They start out teaching the reader about some new functions that do various interesting things: let, if, set!, letrec, and letcc. As in the last book, the reader learns by doing, and you end up implementing a bunch of functions that modify lists of foods in various ways using these built-in functions. Then things get much more challenging as we learn how the built-in functions themselves are implemented in an interpreter written from scratch. It's an extension of the interpreter developed in the last book, and the extensions are even more difficult to comprehend because the implemented functions themselves are more difficult, especially letrec and letcc.
The ramp-up in difficulty was softened somewhat by the pure whimsicalness of the dialogue, sometimes poking fun at LISPers themselves:
How many more conses does deep use to return the same value as deepM
499,500
"A LISP programmer knows the value of everything but the cost of nothing."
Thank you, Alan J. Perlis
(1922-1990).
<Next page>
But we know the value of food!
((((((((((((((((((more pizza)))))))))))))))))
((((((((((((((((more pizza))))))))))))))))
(((((((((((((((more pizza)))))))))))))))
((((((((((((((more pizza))))))))))))))
(((((((((((((more pizza)))))))))))))
((((((((((((more pizza))))))))))))
(((((((((((more pizza)))))))))))
((((((((((more pizza))))))))))
(((((((((more pizza)))))))))
((((((((more pizza))))))))
(((((((more pizza)))))))
((((((more pizza))))))
(((((more pizza)))))
((((more pizza))))
(((more pizza)))
((more pizza))
(more pizza)
more pizza)
Maybe it's not as funny repeated here, but then you'll just have to read the book to get the full effect. I had a blast working through it, and I couldn't put it down. The challenge of fully understanding everything in it was steep, though. I definitely will need to go back through both Schemer books to get a better understanding of how everything works, especially the later chapters. If you enjoy a challenge, don't mind a drastically different writing style for a textbook, and like having a little lighthearted fun in the process, then definitely give this book a chance. Of course, you've already read The Little Schemer, so I didn't even need to tell you that.
The Reasoned Schemer
After whetting my appetite with
The Seasoned Schemer, I was ready for more scheming with this book. It should be stated that
The Reasoned Schemer is not a continuation of the other two Schemer books. It goes off in a completely different direction. Instead of getting further into the theory of computation and how to build a Scheme interpreter in Scheme, this book describes and then builds a language like Prolog for logic programming in Scheme. In fact,
miniKanren is derived directly from the language development of this book.
Once again I thoroughly enjoyed the Socratic dialogue format of the book, and I felt that it was an excellent way to teach and develop the material. Like
The Seasoned Schemer, the dialogue seems at times to be meant to be read straight through instead of having the reader answer the questions directly. Sometimes the questions are nearly impossible to answer with the information already presented, and sometimes the answers ask questions back to the questioner. It's more of a back-and-forth dialogue that's meant to reveal insight rather than direct questions at the reader.
Even with this reader-as-observer format, the reader can attempt plenty of the questions when they are along the lines of, "how is this implemented" or, "what is the result of this code." I did notice that the examples and implementations tended to be switched around compared to the other Schemer books. In the other books, the questions would start with examples using a new function where the reader was asked to predict the results. Then the questioner would move to the implementation of the function. In this book it seemed that as often as not, the implementation questions came first, and the questions on usage examples came after the functions were described. It works both ways, and I'm not sure I have a preference.
Another difference from the other books was a toning down of the sense of humor.
The Reasoned Schemer is decidedly more serious, and that was a bit disappointing. I rather enjoyed the whimsical fun of the other books. The material was still solid and interesting, though, so it's only a minor quibble.
So what does
The Reasoned Schemer cover about logic programming? It starts off with explaining how equality relations work, what fresh and reified variables are, and what unification does. These are all concepts in logic programming that feel very different than other types of programming. Then discussions of conjunctions, disjunctions, and defining relations completes the foundation of logic programming so that we're ready to move on to more complex topics.
Following the basics we build up
conde from conjunctions and disjunctions, and we see that
conde is similar to
cond in Scheme. Then we continue on, building up a number of relations that are similar to the basic functions found in Scheme, like
caro,
cdro,
conso,
nullo,
pairo, etc. Notice that all of these relations end in
o? That's because these functions are just like their Scheme counterparts, except that they are relations. After a few chapters of building up relations associated with familiar functions from Scheme, we delve into a classical application of mathematical logic and build up an arithmetic system from fundamentals, defining addition, multiplication, and exponentiation (and their inverses) with relations. It was really neat, I must say.
After all of these chapters on explaining the language and using it, the last chapter goes through how to implement it in Scheme. It was pretty impressive seeing the whole language built in one chapter, minus a couple functions covered in a short appendix using Scheme macros. The whole experience was super enjoyable, and I'm extremely happy to have read these unique, wonderful books. The Q&A format, the wacky humor, and the strong content made for an excellent time learning Scheme and logic programming. I didn't understand everything the first time around, but that just means I get to read them again. I'm looking forward to it. I highly,
highly recommend all three Schemer books.
Now make yourself a roasted lamb shank with baked spaghetti and cheese.
Enjoy.