(archive 'newLISPer)

September 12, 2009

Updates to nldb

Filed under: newLISP — newlisper @ 15:24

I’ve been making some changes to the newLISP database (nldb.lsp), a small set of functions that provide some rudimentary database-like tools for those occasions when even SQLITE is too heavy. I’ve written about it before – see Simple database in newLISP; it’s currently in use as the database engine for this site, although I think engine is probably the wrong word (think rubber band or sail).

The problems started when I tried to store a list in one of the columns. I had decided that, since the data was stored as a newLISP list, it ought to be able to contain nested lists too. Unfortunately, when I tried to store data using lists, some of the functions stopped working; I hadn’t even considered the possibility that I might want to do that one day.

And the code was already more complicated than necessary. I was jumping through hoops trying to avoid evaluating column names until the last minute. A re-write revealed that there was a simpler solution (isn’t there always?). The original code at the heart of the select-rows function was this:

(if (list? selection-function)
    (dolist (field columns)
        (set-ref-all (expand ''field 'field)
            (row (find field columns)))))
(if (eval selection-function)
    (push row selection -1))

I really didn’t like that! It’s now:

(if (list? selection-function)
    (dolist (field columns)
        (set 'cell (row (find field columns)))
        (set-ref-all field selection-function
            (if (list? cell) 'cell cell))))
(if (eval selection-function)
    (push row selection -1))

This new syntax allows you to supply the function without having to quote every symbol. For example, here is the new simpler syntax for a simple ‘and’ query:

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

It’s still necessary to quote the selector function, because it can be evaluated only after the relevant data has been extracted from the data list.

Another example: return a list of names and symbols and discovery dates of all elements discovered on or after 1900, sorted by year:

(select-rows 'elements
'(>= DiscoveryYear 1900)
'(DiscoveryYear Name Symbol)
(fn (x y) (< x y)))

which returns a list like this:

((1900 "Radon" "Rn")
(1901 "Europium" "Eu")
(1907 "Lutetium" "Lu")
(1913 "Protactinium" "Pa")
(1923 "Hafnium" "Hf")
(1925 "Rhenium" "Re")
(1937 "Technetium" "Tc")
(1939 "Francium" "Fr")
(1940 "Plutonium" "Pu")
(1940 "Neptunium" "Np")
(1940 "Astatine" "At")
; and so on

The functions now work with lists in columns. For example, you could add a list field that contains some keywords for each element. To build the list, push symbols onto the list for the selected rows:

(add-columns 'elements '(Keywords) '())

(change-rows 'elements
'(find  Name '("Iron" "Silver" "Gold" "Zinc" "Tin" "Nickel" "Lead"))
'(push 'Metal Keywords))

This adds the keyword Metal to a few of the more obviously metallic elements. Notice that the symbol ‘Metal has to be quoted here, as it usually would be in newLISP.

The code lives on the Downloads page. If you need help getting it working, let me know.


Leave a Comment »

No comments yet.

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: