opening it up with Common Lisp
Book review: Darwinia
Summer reading: Spin
the Omnivoire's Delimma
the Golem's Eye
I was tracking down a problem in CL-Graph's random graph generation code that only seemed to be happening in Allegro. Here's the story.
It was a dark and stormy night. Somewhere, a dog howled. The Common List container library includes several classes that stand in for their Common Lisp counterparts (it also does a good job of providing methods so that regular Lisp data structures behave properly with the container library's methods but that's a different story). One of these is the vector-container. CL-Graph uses vector-containers to hold an array of edges attached to each vertex. When an edge is deleted, something very like the following gets executed:
(setf vector-edges (make-array 1 :initial-contents '(1) :adjustable t :fill-pointer t)) (setf vector-edges (delete 1 vector-edges :count 1))
The trick is that under Allegro, the vector returned by delete may no longer be adjustable. At first, I thought that this had to be an error. However, the Hyperspec says that
which, if I'm reading it correctly, means that Allegro is within the letter of the law. On the other hand, this also seems like a dumb thing. What if I want to delete something else? What if I want to adjust the array later? Why is Lisp like this (probably for efficiency and because this is what some vendor had already done before the standard writing got underway...).
More to the point, what do I do now? Do I make two calls to subseq (ugh?); do i swap the element to be deleted with the last element and then shrink the array (not hard but it irritates me that i have to think about this...). Is there some other technique I'm overlooking (I hope so even if it does make me look silly!)
Copyright -- Gary Warren King, 2004 - 2006