> Because namespaces are mutable, even if I were to perform a rename correctly, the old name is still present in the namespace.
First, ns-unmap your old name (a refactoring tool should do that for your, I guess). (edit: Clojure is a Lisp-1).
> 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.
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.
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.
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.
But again, you should be careful when you rename namespaces. Maybe the best answer is to simply be aware of the possible pitfalls.
> Because namespaces are mutable, even if I were to perform a rename correctly, the old name is still present in the namespace.
First, ns-unmap your old name (a refactoring tool should do that for your, I guess). (edit: Clojure is a Lisp-1).
> 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.
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.
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.
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.
But again, you should be careful when you rename namespaces. Maybe the best answer is to simply be aware of the possible pitfalls.