DataScript: Immutable database and Datalog query engine in ClojureScript
github.com
github.com
I love living dangerously, if danger means using full-stack Clojure and immutability -grin-
It's also well-suited for rapid-prototyping. I'm working on a small project that will eventually need a backend, but for now I just store everything in a datascript db and serialize that to localStorage. When I'm ready to add a backend, I'll just subscribe to datascript's transaction queue and forward them to be saved on the server.
Would love to hear comments from anyone who has given DataScript a test drive - I'm guessing from the alpha state that no one is using it in production but hey, who knows... some people like to live dangerously.
There are some times when having a novel way to query could lead to simpler data.
I wanted something like this for Go recently, settled with SQLite :(
for bonus points, it uses rethink as the backing store
These days everybody seems to throw around terms like immutable, isomorphic, pure etc. without actually knowing what they mean, or using them in contexts whey they don't make any sense.
You wrap that data-structure/database in a mutable reference type (an atom), like you do with any other data-structure in clojure if you need change.
> In computing, a persistent data structure is a data structure that always preserves the previous version of itself when it is modified. Such data structures are effectively immutable, as their operations do not (visibly) update the structure in-place, but instead always yield a new updated structure.
The way I understand it in terms of python: It's like a nametuple or dict, where each update return a new namedtuple/dict with the new values for modified attributes but still the old values for attributes that did not change. It doesn't need to deep copy all the datastructure/database.
This is not persistent as in "stored on disk". Being append only is a way to achieve persistence except it is also applicable to non-stored-on-disk datastructures.
(Fully) persistent data structures are absolutely wonderful. It's a pity that more languages don't have syntactic sugar for them.
You don't write to the database, you perform an operation that takes a database and a write request and returns a new database. Same with updates. Essentially, the kind of things you think of as "mutating" operations have a signature of, in Haskell-ish notation:
db -> operation -> db tx_report = datascript.transact(db_conn, [{:key "value"}]);
set_db_to_render_from(tx_report.db_after);
send_report_to_server(tx_report, function(error) {
set_db_to_render_from(tx.report.db_before);
});With datomic you are just adding a new fact. My address is now x. This has a lot of nice properties. I can now easily write a query to tell me your previous 5 addresses, rolling back is easy, you can get amazing and scalable read performance, etc etc
In the past we have either had to hand roll our own features (e.g. Have a table of past addresses, or add date columns to specific tables) or rely on error prone/brittle techniques like using audit tables, source control, or transaction logs.
Datomic makes it easy!