I am trying to build datalog queries programmatically, but keep running into the problem that I will illustrate with an example function:
(defn test-expr [attribute]
`[?entity ~attribute ?value]])
When I run (test-expr 3), I would expect the output:
[?entity 3 ?value]
But instead, I get
[mynamespace/?entity 3 mynamespace/?value]
Which obviously is not what I want. Is there a way to tell clojure "please just quote the list and expand variables I tell you to?"
Yes, there is.
(defn test-expr [attribute]
`[~'?entity ~attribute ~'?value])
Here you first unquote the syntax quotation and then immediately quote the symbol (~'
construct) again. The result is namespace-less symbol.
It is equivalent to the following, which explains how it works:
(defn test-expr [attribute]
`[~(quote ?entity) ~attribute ~(quote ?value)])
What you're looking for is the backtick library by Brandon Bloom https://github.com/brandonbloom/backtick
It was built for the exact problem you describe. It supplies a command named 'template' that works like the backtick but without the namespacing stuff.
In Clojure, quasiquotation and namespace resolution are mixed together in a single feature. This has great benefits for writing macros in a language like Clojure, which is a "Lisp-1" (as opposed to Common Lisp, which is a "Lisp-2", with separate namespaces for functions and variables.)
I also agree that it might have been better not to conflate these features, but it would have made the writing of macros in Clojure less elegant, so I can see why it works the way it does.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With