Question

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?"

Was it helpful?

Solution

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)])

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top