This project contains a custom scheme interpreter, able to run schemeKV, a s-expression-based key-value database.
The basic scheme interpreter is from this well-known tutorial (can be found in the 'base' branch).
I extended the interpreter to include functionality for hashtables and network sockets, implemented as bindings to the corresponding haskell packages Data.Hashtable and Netwock.Socket and other common scheme features not included in the tutorial.
The scheme files for the database are located in src/. They include a server.scm and client.scm file.
What's special about schemeKV is that all set
, get
, etc. requests are sent as scheme s-expressions
and evaluated by the server, making use of scheme's homoiconicity.
This means that the database can not only store strings or numbers, but entire scheme expressions.
Running client.scm after connecting with the server:
Scheme-KV> (set 'string "test")
"test"
Scheme-KV> (get 'string)
"test"
Scheme-KV> (set 'increment '(lambda (x) (+ x 1)))
(lambda (x) (+ x 1))
Scheme-KV> (ev ((ex 'increment) 5))
6
Scheme-KV> (pers 'increment)
"Data saved."
Scheme-KV>
The ability to store lambda expressions is especially useful for storing macros.
One could store a macro like (lambda (k) (if (< (get k) 18) "Not saved." (pers k)))
,
which could take in the key of a newly created key-value pair containing the age of a person.
The macro would then only make the key-value pair persistent on disk, if the age is above 18.
This feature makes the database program extensible by the user.
set
: create key-value pairget
: get the value stored at keydel
: delete the value stored at keyex
: evaluate the expression stored at key (mainly useful for stored lambda-expressions)ev
: evaluate any scheme expressionpers
: save the key-value pair at key to a file to make it persistent
The interpreter can be built with cabal.