I often find myself wishing for a reader macro that is between quote ' and syntax-quote `: I want to use unquote ~ and unquote-splicing ~@ but I do not want to get fully-qualified symbols. Let’s have an example.
;; What I want:
user=> (let [a 1] (magic-quote (let [x 0] (+ x ~a))))
(let [x 0] (+ x 1))
;; What the usual suspects do:
user=> (let [a 1] `(let [x 0] (+ x ~a)))
(clojure.core/let [user/x 0] (clojure.core/+ user/x 1))
user=> (let [a 1] '(let [x 0] (+ x ~a)))
(let [x 0] (+ x (clojure.core/unquote a)))
It seems to me that this magic-quote macro would be possible to implement but tricky. Does anyone know of an implementation, or maybe I am overthinking it and there is some easy way to do it?
Yes, sure; auto-gensym is great for macros but it’s not what I’m looking for. I’m not actually trying to generate Clojure code here, it was just the first example I had on my mind.
Oh, that’s pretty simple actually. There’s the caveat that if you want to have a fully-qualified symbol somewhere, it’s going to get unqualified, but that’s not always an issue.
Yeah, that’s a little more complicated… One way I can think of is by sending in a quoted form (not syntax quoted) and edit that… and just handle clojure.core/unquote when you get to it. And then grabbing the unquoted symbol from the locals using &env.
@teodorlu yeah, that works. But Miikka was looking for a thing where literally unqualified symbols don’t automatically get expanded to qualified symbols.
backtick is definitely the tool to use for the closest semantics to Clojure’s syntax unquote. As a tagged literals, #mq/' ends up applying its gensyms across nesting levels, so you end up with a pretty different templating gensym semantic.
If you want to try #mq/' from a git dep, here it is. Let me know if you find this method useful for anything.
Oh, I see. So you would want "syntax quote with ability to insert stuff but without resolving namespaces. And I have to admit that I hadn’t considered gensyms or “nested use”.
I’ve wished for this many times, but can’t remember why. This time it was because I wanted to generate some Z3 code. It conveniently has Lisp syntax. Here’s my code using backtick. Not amazing, but a bit nicer than generating strings.