Going into chapter two of Paradigms of Artificial Intelligence Programming, we get a deceptively simple program to experiment with. The code for this chapter is located in the file simple.lisp, but note that the file does not include the mappend function from section 1.7. (And you thought that “mappend” was just a clever play on words!!)
The whole purpose of this chapter is to compare two approaches to programming. One translates a problem into code following a “quick and easy path” that appears to be the “simplest” but locks your solution into hard coded assumptions. The other approach uses data to describe the problem at a higher, more abstract level. The functions that “do the work” can be attached to varying data sets… and therefore can solve what, on the surface, appear to be different problems. Also, he demonstrates how the same data can be used for different programs. He promises to use this latter, more abstract approach throughout the book. He calls it a “Rule-based” approach, and says that it’s more work for small problems, but that it minimizes the amount of the solution that’s “written directly in Lisp.”
Norvig’s treatment of the chapter is different because he emphasizes dynamism and code reuse on all sides of the problem. I typically think in terms of data driven design being a way to allow for infinite customization within a single clearly specified problem. Somehow, Norvig’s abstractions are “hairy” at both ends… allowing for an order of magnitude more flexibility. I do some of the things he demonstrates already. For instance, he uses a list to store data and even includes extra non-functional fluff to make it more readable. Then he makes the Lisp equivalent of property accessors in order to allow the program to be self commenting and easier to modify later. But there’s something about the way he thinks that’s foreign to me… or at least, does not come naturally. He doesn’t quite make such a hard separation between code and data that my experiences with OOP Frameworks and Relational Databases have drilled into me.
The chapter really should be no big deal, but my attempts at exercises 2.1 and 2.2 blew up in my face. The first one wasn’t too bad, but I was ignorant of the fact that setf could be used with lexically scoped variables– and also that setf returns the value. Not knowing those two things can lead to some pretty ugly Lisp code, so I’m glad I’ve learned them. The second exercise I completely misunderstood. I don’t know why. Maybe it has something to do with the fact that his “rewrite” function is named in a counter-intuitive way. I even completely missed it after glancing at the answer. Why is it that when Norvig asks me to do something pretty simple I completely blank out?
At this point I should either keep on moving and start on the next chapter… or I should go back an reread Chapter 2 and try to soak up everything he said without missing anything. I can’t tell if I’m overreacting or not. At any rate, Norvig’s writing is fairly dense and requires a great deal of attention. You can’t just skim it and expect to get much out of it.