Every query language answers questions. The difference is how much of what you write is the question — and how much is plumbing.
{:pull
[(tracks-by "Miles Davis")
:dc/title
{:dc/creator [:foaf/name]}
{:review/has
[:review/stars
:review/text]}]}
Tracks from a triplestore. Reviews from Postgres. One query.
Here's what SPOQE generates from that.
PREFIX dc: <http://purl.org/dc/elements/1.1/> PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT ?track ?title ?name WHERE { ?track dc:creator ?artist . ?artist foaf:name "Miles Davis" . ?track dc:title ?title . ?artist foaf:name ?name . }
SELECT stars, text FROM reviews WHERE track_id IN ( 42, 87 )
Name a pattern, reuse it everywhere. The definition is inspectable — no hidden magic.
;; A reusable pattern (defn tracks-by [name] {:from [?t :mo/Track] :filter (= [:dc/creator :foaf/name] name)})
(tracks-by "Miles Davis") (tracks-by "John Coltrane") (tracks-by "Thelonious Monk")
;; See exactly what happens (explain (tracks-by "Miles Davis"))
The ceremony still happens — SPOQE generates the SPARQL and SQL.
Run (explain ...) to see every step. Copy it, modify it, run it directly.
The semantic web gave us precise, reusable names for everything. SPOQE gives those names a language that doesn't make you stutter.