Basically, the problem concerns access to other namespaces via :use
or :refer, though in practice it is most important for clojure.core
that is referred to by default in any namespace. A symbol that refers
to a var from another namespace cannot be redefined. If I introduce a
symbol in my namespace and in a later release the same symbol is
defined in a namespace that mine refers to, I can no longer compiler
my namespace.
For namespaces other than clojure.core, an acceptable solution is to
use the :only keyword in the :use clause of the ns macro. This just
requires a bit more work in typing, but I don't see any other
potential difficulty. I am currently converting all my code to
use :only, and I haven't had any bad surprises until now. For
clojure.core, listing all imported symbols explicitly would be a real
pain, but I don't see any other simple solution. I just hope someone
else does :-)
Konrad.
> I think :exclude is what you want
>
> (ns my-ns
> (:refer-clojure :exclude [get replace]))
Not quite, as exclude requires me to know what I want exclude.
What I want is "exclude everything that wasn't there in version X.Y".
Konrad.
> For namespaces other than clojure.core, an acceptable solution is to
> use the :only keyword in the :use clause of the ns macro. This just
> requires a bit more work in typing, but I don't see any other
> potential difficulty. I am currently converting all my code to
> use :only, and I haven't had any bad surprises until now. For
> clojure.core, listing all imported symbols explicitly would be a real
> pain, but I don't see any other simple solution. I just hope someone
> else does :-)
I'm a clojure newb, but couldn't you reflect on a given version to
generate an import file that used :only to import every name visible
in that version? Then you could import that file, which would be a
version constant (although I'm not clear yet if clojure allows
transitive imports). It should be easy to generate such a file
privately for any given snapshot (although I imagine it would be best
as an official version artifact).
Alternatively of course every name could be tagged with version
metadata and import enhanced to take a version spec, but that seems
far more intrusive (and in any case precisely equivalent to my first
suggestion).
Antony Blakey
-------------
CTO, Linkuistics Pty Ltd
Ph: 0438 840 787
There are two ways of constructing a software design: One way is to
make it so simple that there are obviously no deficiencies, and the
other way is to make it so complicated that there are no obvious
deficiencies.
-- C. A. R. Hoare
> 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!
Konrad.
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)