-
Notifications
You must be signed in to change notification settings - Fork 127
Description
- Imagine you are writing a test that operates on namespaces, but you don't want it to conflict with other tests that operate on namespaces, so you give the namespace a long name nested "within" your test namespace, like pixie.tests.test-stdlib.foo. Then, because you want to refer to that namespace several times within the test, and you don't want to write it out each time, you assign it to a local, like this.
(let [test-ns :pixie.tests.test-stdlib.foo]
(in-ns test-ns)
(def y 3)
etc. etc.)
Except the test fails. You expected that y would be created within pixie.tests.test-stdlib.foo, but instead it's created within namespace "test-ns". That's because in-ns is a special form at compile time, and it sets the compile-time namespace to "test-ns". Then it becomes a function at run time, and it sets the run-time namespace to pixie.tests.test-stdlib.foo, as you would see if you examined *ns*. I think that behavior is confusing.
- In the same vein, in-ns affects the environment even if never executed.
user => (defn g [] (in-ns :pixie.tests.test-stdlib))
<Var user/g>
pixie.tests.test-stdlib =>
So in this case, even though g was only compiled but not executed, it affected the current namespace. Similar stuff happens with if statements -- if you have an if statement in which one branch sets the namespace to :foo and another to :bar, all vars resolved after that will be resolved in the namespace of the second branch, etc.. The only thing that matters is the order in which the compiler encounters in-ns.
I think having the compiler mutate the current namespace as it goes along is confusing, because it requires you to think about order of compilation. It requires non-local reasoning to figure out which var an unqualified symbol refers to -- not just looking at what's lexically-enclosing. This is unlike in clojure, where if you read through a file of function definitions all in one namespace, then you know how every symbol will be resolved simply by looking at its name (okay, with the exception of refers).
What advantage does pixie gain by having in-ns be a special form that affects compilation state?