Your first program
Save this as hello.clj:
(require '[datomic.api :as d])
(d/create-database "datomic:mem://hello")
(def conn (d/connect "datomic:mem://hello"))
;; Install one attribute.
@(d/transact conn [{:db/ident :person/name
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one}])
;; Add two people.
@(d/transact conn [{:person/name "Ada"} {:person/name "Grace"}])
(prn (sort (d/q '[:find [?n ...] :where [_ :person/name ?n]] (d/db conn))))
Run it
clonim run hello.clj --source-path path/to/nitomic/src
clonim run compiles the program through Nim and runs it. It prints:
("Ada" "Grace")
The query returns its results in no particular order, so the program sorts them before printing.
Build a binary
clonim build hello.clj --source-path path/to/nitomic/src
clonim build produces a standalone native executable instead of running
the program. Release builds (-d:release) are what you want for speed: built
this way, the full Seattle walkthrough runs in about 1.3 seconds.
What just happened
The program uses nothing but datomic.api, so the same file also runs on the
JVM against Datomic Pro. A few things to notice:
datomic:mem://hellonames an in-memory database, gone when the program exits.datomic:sql://hello?jdbc:sqlite:hello.dbwould keep it in a SQLite file instead (see Durable storage).d/transactreturns a future. Dereferencing it with@waits for the result, a map with:db-before,:db-after,:tx-dataand:tempids. A failed transaction throws when you dereference it.- Maps without
:db/idget implicit tempids. Each map in the second transaction becomes a new entity. [?n ...]is a collection find spec: the query returns a vector of names instead of a set of tuples.
The Getting started walkthrough covers all of this, and much more, on a realistic data set.