Tuesday, January 24, 2006

custom setf forms

Norvig presents several ways of creating custom setf forms, but none of them as elegant as Grahams:

(defun get-route (id table)

(defun (setf get-route) (rt id table)

The other options are something like the macro defsetf, or even more complicated beasts. I ran across the above need in code I was writing, and happened to be reading Norvig. He shows the ugly (to my mind) way of doing it, and I had to pull out my ANSI Common Lisp by Graham to find the pattern that had been tickling the back of my head.

There is an annoying downside to the setf form in something like our routing table when it comes to testing. Our routes are objects with several properties, including id, address, proximity, etc. I have a convenience function called make-random-route, that generates a route for me with all the slots, um well randomized (I'm figure you could have guessed that). Previously, I could insert a test route with (insert-route (make-random-route)). I wanted to use the setf form, since that seemed to follow lisp conventions better. This means that to do the same means

(let ((rt (make-random-route))
(setf (get-route (id rt)) rt))

Practically speaking, in the real world, we would be creating a route object before we would ever consider inserting it, so the let form is not really an additional burden. I just happened to run into it because of the testing.


Post a Comment

<< Home