So there we are with a version of defn, which I called defn! because it is even more agressive than defn in its side effects, that could solve your problem :
(defmacro defn! "Like defn, but first ensures that if name is bound to something (e.g. the name of a function in a 'used' or 'required' namespace, it is first unbound)." [name & body] `(do (clojure.core/ns-unmap *ns* (quote ~name)) (eval (quote (clojure.core/defn ~name ~...@body))))) I chose to use eval, even if it's not the usual recommended way, because I really wanted to not duplicate the logic in defn regarding definition of multiple arity functions, meta data, ... But I'm not sure it is correct to have twice ~name in the macro expansion. I thought that as name is expected to be the name for a symbol without evaluation (as is required for the name in defn), I could do this ? If you find this interesting, please feel free to add it to clojure-contrib. I think the same thing could be done for defmacro (defmacro!), ... and other defXYZ.. functions/macros as well .. ? HTH, -- Laurent 2009/3/3 Christophe Grand <christo...@cgrand.net> > > Konrad Hinsen a écrit : > > On 03.03.2009, at 00:53, Laurent PETIT wrote: > > > > > >> I'm able to do that from the REPL when done one by one : > >> (clojure.core/ns-unmap *ns* (quote filter)) > >> (clojure.core/defn filter [] "oh my!") > >> > >> thus correctly redefining the binding of filter for the rest of use > >> by the ns > >> > >> But I can't manage to get it work from a macro (indeed not even > >> when directly called inside a do) : > >> > >> (do (clojure.core/ns-unmap *ns* (quote filter)) (clojure.core/defn > >> filter [] "my map!")) > >> > >> What is wrong with me ? (Something with def I still haven't > >> understood, I think) > >> > > > > I can only confirm your observation, and say that I don't understand > > it either! > > > In the first case, when you enter the second statement at the repl, > filter is unmapped already so the compiler understands that it must > create a var and intern it as my-ns/filter. > In the second case, both statements are bundled in one expression: when > the expression is compiled filter is still mapped in the current ns and > the compiler refuses to compile the def form. > > Adding an eval can make that works: > > (do > (clojure.core/ns-unmap *ns* (quote filter)) > (eval '(clojure.core/defn filter [] "my map!"))) > > > but it may be simpler to explore doing something like this: > > (do > (clojure.core/ns-unmap *ns* (quote filter)) > (clojure.lang.Var/intern *ns* 'filter (fn[] "my map!"))) > > > Christophe > > -- > Professional: http://cgrand.net/ (fr) > On Clojure: http://clj-me.blogspot.com/ (en) > > > > > > --~--~---------~--~----~------------~-------~--~----~ 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 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 -~----------~----~----~----~------~----~------~--~---