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
-~----------~----~----~----~------~----~------~--~---

Reply via email to