TL;DR: forking Clojure to fix namespaces.<p>> Because namespaces are mutable, even if I were to perform a rename correctly, the old name is still present in the namespace.<p>First, ns-unmap your old name (a refactoring tool should do that for your, I guess). (edit: Clojure is a Lisp-1).<p>> What if we gave Namespaces and Vars version numbers? When a Namespace is re-defined (the ns form is evaluated) then the Namespace's version is incremented. When a def is evaluated, the version of the Var bound by the def is set to be the version of the Namespace in which that Var exists.<p>Your environment could keep track of definitions and usages of your symbols (see for example slime-who-calls, etc.). That would be a good improvement for Clojure.<p>There is another problem: define namespace N, define variable N/x, using it in another namespace M, remove namspace N. Then, an old name x is referenced from M which does not exist in any namespace. Also, you redefine namespace N with a new x, and now old-x and new-x are different objects. I don't think version numbers would help you here.<p>I am just thinking aloud, but when remove-ns is called, you could re-parent orphaned names from that package to a global "orphans" table. When you intern a symbol in a namespace, first you try to see if you can recycle objects from "oprhans" based on their fully qualified name. So that new-x and old-x are in fact the same name object.
Or, you just use a global map to store fully qualified names in the first place. Maybe the metadata attached to orphaned symbols should be cleared in this approach, to avoid keeping irrelevant data about a name when it is reused.<p>But again, you should be careful when you rename namespaces. Maybe the best answer is to simply be aware of the possible pitfalls.