The backtick namespace-qualifies symbols automatically:

(macroexpand-1 '(switch-foo-library! x))
;=>
(clojure.core/defn
 user/foo
 [y__3652__auto__]
 ((clojure.core/resolve (clojure.core/symbol (clojure.core/str x "/foo")))
  y__3652__auto__))

The error is about the "user/foo" name of the defn.

You can fix this by quoting the symbol then immediately unquoting it:


(defmacro switch-foo-library! [x]
  `(defn ~'foo [y#] ((resolve (symbol (str ~x "/foo"))) y#)))
;=> #'user/switch-foo-library!
(macroexpand-1 '(switch-foo-library! x))

;=>
(clojure.core/defn
 foo
 [y__3946__auto__]
 ((clojure.core/resolve (clojure.core/symbol (clojure.core/str x "/foo")))
  y__3946__auto__))


However what you really want probably something with with-redefs 
<http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/with-redefs>
:

(defmacro with-ns [ns vars & body]
  {:pre [(symbol? ns) (nil? (namespace ns))
         (every? #(and (symbol? %) (nil? (namespace %))) vars)]}
  (let [bindings (vec (mapcat #(do [% (symbol (str ns) (str %))]) vars))]
    `(with-redefs ~bindings ~@body)))
;=> #'user/with-ns
(ns alt)
;=> nil
(def juxt (constantly (constantly "NEW JUXT")))
;WARNING: juxt already refers to: #'clojure.core/juxt in namespace: alt, 
being replaced by: #'alt/juxt
;=> #'alt/juxt
(in-ns 'user)
;=> #object[clojure.lang.Namespace 0x77b2abef "user"]
(with-ns alt [juxt] (map (juxt :a :b) (repeat 4 {:a 1 :b 2})))
;=> ("NEW JUXT" "NEW JUXT" "NEW JUXT" "NEW JUXT")
((juxt :a) {:a 1})
;=> [1]



If you want to make the var change permanent (i.e. not requiring your body 
be inside with-redefs), you can use alter-var-root 
<http://clojuredocs.org/clojure.core/alter-var-root>, but you have to take 
care to allow the vars to be restored somehow, e.g. by storing the old 
mappings somewhere and providing a macro to save and restore them.

It's possible someone has scratched this itch before, too: there might be a 
utility library out there somewhere that does something like this.

On Tuesday, April 5, 2016 at 9:10:15 PM UTC-5, Will Bridewell wrote:
>
> I'm working on some code where I want to evaluate different 
> implementations of the same functionality. Each implementation of a 
> function lives in its own namespace. For example, suppose that I have the 
> following simplified code.
>
> (ns tst1)
> (defn foo [x] (+ x 1))
>
> (ns tst2)
> (defn foo [x] (+ x 2))
>
> (ns tst3)
> (defn foo [x] (+ x 3))
>
> (in-ns 'user)
>
> What I'd like to do is call a macro that binds the function name in user 
> to the function in one of the libraries. The call would look like one of 
> these. 
>
> (switch-library! 'tst1 'foo)
>
> (switch-foo-library! 'tst1)
>
> The closest that I got was to do 
>
> (defmacro switch-foo-library! [x]
>   `(defn foo [y#] ((resolve (symbol (str ~x "/foo"))) y#)))
>
> That's kind of embarrassing, but I think it does what I want. However, 
> suppose I do
>
> (ns-unmap 'user 'juxt)
> (defmacro switch-juxt-library! [x]
>   `(defn juxt [y#] ((resolve (symbol (str ~x "/juxt"))) y#)))
>
> Now I get 
>
> CompilerException java.lang.RuntimeException: Can't create defs outside 
> of current ns, compiling:
>
> Well, gosh. I can't play around with symbols in clojure.core? What's 
> happening here?
>
>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to