Q:

Clojure macro throws "CompilerException java.lang. IllegalStateException: Var clojure.core/unquote is unbound" when called

I'm trying to write a clojure macro that lets me call a function and retrieve the arguments from a map/struct using the provided key values such as:
   (with-params  {:apple 2 :banana 3 :cherry 7} + :apple :banana)
   ;; 5

but when I try to use the macro that I wrote:
(defmacro with-params [s f & symbols]
  `(~f ~@(map ~s ~symbols)))

calling 
   (with-params  {:apple 2 :banana 3 :cherry 7} + :apple :banana)

gives me
#<CompilerException java.lang. IllegalStateException: Var clojure.core/unquote is unbound. ( NO_SOURCE_FILE:0)>

Could someone help me understand how syntax-quoting works here? 

A:

For what it's worth, this shouldn't be a macro anyway.  A function is plenty powerful, and the macro version will only work if both the map and the keywords are given as compile-time literals. 
(defmacro with-params-macro [s f & symbols]
  `(~f ~@(map s symbols)))

(defn with-params-fn [s f & symbols]
  (apply f (map s symbols)))

user> (with-params-macro {:x 1} (fn [z] z) :x)
1
user> (let [params {:x 1}] 
        (with-params-macro params (fn [z] z) :x))
nil

user> (let [params {:x 1}] 
        (with-params-fn params (fn [z] z) :x))
1

A:

The reason that `(~f ~@(map ~s ~symbols)) doesn't work is that the compiler chokes on the unnecessary unquote (~) inside the unquote-splicing (~@).  The unquote-splicing unquotes the outer syntax-quote (`), so the inner two unquotes don't have any matching syntax-quote, which is why you were getting the "unbound" error. 
What you want to do is evaluate (map s symbols) first to get the sequence of operands, then pass the flattened result to the function (~f); therefore the correct version is:
(defmacro with-params [s f & symbols] `(~f ~@(map s symbols)))

You can easily verify this with:
(macroexpand '(with-params {:a 1 :b 2 :c 5} * :a :b :c))    ;; (* 1 2 5)
(with-params {:a 1 :b 2 :c 5} * :a :b :c)                   ;; 10

