One place where Clojure currently requires namespace-qualified keywords is when using the extend
function function to add an implementation of a protocol to an existing type. (This is 1.2 functionality, available with the latest snapshots, but not the 1.1 stable release.) The relevant snippet from (doc extend)
:
extend takes a type/class (or interface, see below), and one or more
protocol + method map pairs. It will extend the polymorphism of the
protocol's methods to call the supplied methods when an AType is
provided as the first argument. Note that deftype types are specified
using their keyword tags:
::MyType or :my.ns/MyType
Indeed, for an Apple type and an Eatable protocol:
(deftype Apple [colour])
(defprotocol Eatable (eat [x]))
the following throws an exception (No implementation of method: :eat
etc.):
(extend :Apple Eatable {:eat (fn [x] (println (str (name (:colour x)) ", yummy!")))})
(eat (Apple :red))
while this prints out red, yummy!
:
(extend ::Apple Eatable {:eat (fn [x] (println (str (name (:colour x)) ", yummy!")))})
(eat (Apple :red))
Note I've just typed it all in at the REPL. Also note that if you want to reproduce it, it's best that you type / paste it in in the order given above; e.g. reevaluating either of the (deftype Apple [colour])
and (defprotocol Eatable (eat [x]))
forms (or even both) does not make Clojure forget about the protocol implementation.
Again, this is a 1.2 feature, so it's not even there in 1.1 and might change prior to the actual release of 1.2.
Sharing a hash-map between a number of namespaces is another possible use case, as Brian says. Note that there's no need for a reference type to be involved. Say there's a bunch of libraries -- which may perhaps be added to in the future -- which manipulate (maybe transform, maybe just observe) hash-maps keyed by keywords, where each library is free to define which keywords it looks for and what it uses them for; then one might be tempted to use namespace qualified keywords to avoid collisions.
Actually, there currently exists an example which is not at all contrived, namely the Ring spec v0.1 (a key piece of the present day Clojure Web ecosystem). See the Request and response map keyword namespacing message to the Ring Google group (made by Ring author
Mark McGranaghan) for some insight into the rationale behind that design decision, as well as behind the decision to no longer require namespacing keywords in Ring spec v0.2. There's also a message by James Reeves (the author of Compojure) in support of the change.
Ultimately, as all namespacing, this is a collision avoidance feature. Clojure code that is written nowadays doesn't tend to care about having "private" keywords, so they don't see much use; but it is good to have them available for when they may make a difference.