This is a collection of blog entries written while learning Lisp. It is posted in the order written so you probably want to jump to the first post.

Saturday, October 13, 2007

Practical Common Lisp Chapter 3 : A Simple Database

Chapter 3 was quite good. It was an actually little program that did something while introducing you to a lot of concepts in Lisp. From io, loops and even a little bit about macros. There was just enough in the text that I could follow along in Emacs. It went at a good pace and I learned a lot of new things. I will probably have to go back and review things, but coding up everything as it went along really helped.

The parameter ability of Lisp is really cool, so many brain cells have been spent making functions with few arguments and pondering their order so that don't end up with functions where you have to put in default values just to change the last one.
Meanwhile in in Lisp you can put in the last one using its keyword. And not to forget the supplied-p parameter! I guess I have been coding in other languages for so long that the ideas of having that feature would have never occurred to me.

(defun foo (&key a (b 20) (c 30 c-p)) (list a b c c-p))

(foo :a 1 :b 2 :c 3) ==> (1 2 3 T)
(foo :c 3 :b 2 :a 1) ==> (1 2 3 T)
(foo :a 1 :c 3) ==> (1 20 3 T)
(foo) ==> (NIL 20 30 NIL)

Below are my notes for this chapter.

When implementing dump-db, it should mention that to run it do: (dump-db).

When I run add-cds there is a newline before Ripped and Another while in the book there was not.

Title: Give Us a break
Artist: Bimpopo
Rating: 10

Ripped [y/n] (y/n) y

Another? [y/n]: (y/n) n

When writing save-db I get the following warning which also prevents it from being run until I remove that line:

keyword :IFEXISTS is not allowed for function OPEN.

It says that I can do the following statement, but when run returns nil:

CL-USER> (select (where :rating 9 :ripped nil))

After a few minutes I figured out that this was correct because every cd was marked as ripped in the database. It would have been better to do:

(select (where :rating 9 :ripped t))

Updating the Dixie Chicks to 11 didn't output nil, but outputed the entire list.

CL-USER> (update (where :artist "Dixie Chicks") :rating 11)
((:TITLE "Give Us a break" :ARTIST "Bimpopo" :RATING 10 :RIPPED T)
(:TITLE "Ben Folds" :ARTIST "Rockin' the suburbs" :RATING 6 :RIPPED T)
(:TITLE "Home" :ARTIST "Dixie Chicks" :RATING 11 :RIPPED T)
(:TITLE "Fly" :ARTIST "Dixie Chicks" :RATING 11 :RIPPED T)
(:TITLE "Roses" :ARTIST "Kathy Mattea" :RATING 7 :RIPPED T))

No comments: