(archive 'newLISPer)

January 30, 2009

Simple database, second attempt

Filed under: newLISP — newlisper @ 22:47

Rewriting is part of a writer’s job, and with practice it’s easy to be ruthless about your previous drafts. This chap has written more about the process than I ever could.

But it’s slightly harder for me to be ruthless when editing code, because once I manage to get something working, I’m reluctant to break it just to try and make it better. But I’m slowly getting the hang of this too.

The simple database I started working on recently was OK, but there were things I didn’t like about it. Perhaps the main problem area was with the way I switched between a simple list of lists:

((1 1.0079 "Hydrogen" "H" -259 -253 0.09 0.14 1776 1 13.5984) 
 (2 4.0026 "Helium" "He" -272 -269 0 0 1895 18 24.5874) 

to a list of association lists, where the keys were the ‘column’ names:

(((No 1) (AtomicWeight 1.0079) (Name "Hydrogen") ... )
 ((No 2) (AtomicWeight 4.0026) (Name "Helium") ... )

This happened all the time; virtually every function did this conversion process. Before any rows could be selected, the whole table had to be modified, with keys inserted before every value. Not a good idea with large tables!

So I abandoned the association list approach. You don’t really have to use lookup, because nth and find can do a similar job, albeit less easily:

(setf (nth (find column-name columns) row) (eval modify-fn))

I had to rewrite many of the functions, too, because now you always have to know the name of the table you’re working on (before, you didn’t, because the association list’s keys were all you needed). It’s a little less easy on the eye now, but more powerful. To select rows, you do this:

(select-rows 'elements '(and (> 'EarthCrust 1) (< 'DiscoveryYear 1900)))

which is slightly different to the old way (there’s no where any more):

; old version
(select-rows 'elements (where (and (> 'EarthCrust 5)) (< 'DiscoveryYear 1900)))

The select-rows function now also does column filtering and sorting:

  'elements                               ; table
  '(> 'EarthCrust 1)                      ; selection criterion
  '(Name Symbol)                          ; columns to return
  'Symbol                                 ; column to sort by
  '(fn (x y) (> (length x) (length y)))   ; sort function 

(You can perhaps see why I still think it would be cool to have named parameters…!)

I’ve also re-written change-rows so that it can access all columns when making a change. The idea here is that you can change a column’s value using a newLISP expression that can access information from other columns in that row:

  'elements                 ; table              
  '(ends-with 'Name "ium")  ; selection criterion        
  'MP                       ; column to modify 
  '(dec 'BP)                ; expression to apply to column        

This changes the Melting Point of every “ium” element to be one less than its Boiling Point. (Yes, I noticed that the ‘BP is quoted, when it normally wouldn’t be, but it’s already been replaced by the actual value when the dec function is called.)

So far, it’s looking promising, not much slower than a SQLite database, and doing the same job with fewer functions.

If you’d like to see the second attempt, you can find it here, and there’s a simple database to practice with here. I’d be very grateful for any improvements you can suggest!



  1. here and here are dead links!

    Comment by some guy — February 11, 2011 @ 18:58 | Reply

  2. Most of the links broke when I imported them into wordpress. I just don’t have the energy to fix them all. Links to other posts can be found using the search box .. :)

    Comment by newlisper — February 11, 2011 @ 20:52 | Reply

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: