A little trick that I use, when I need to refer to “the current namespace”, is to put this after the ns form:
(def ^:private my-ns *ns*)
That is resolved at load/compile time, before the code is actually run, so it binds my-ns to the actual namespace and not user which is the namespace that Clojure itself starts up in I believe.
I think I know why it does this actually. It makes sense when you think about it.
As namespaces are required, they get loaded and evaluated. They are evaluated top to bottom. So when they encounter ns, the namespace changes, and then when it encounters the -main, it is defining the function inside your test.core namespace.
After everything is required transitevely, it jumps back to the namespace of the first thing that was required, which in this case would be the bootstrapping namespace. In the case of lein, that is user.
Now from that namespace, it calls your -main function. That particular call stack is thus initiated from user.
When one namespace calls a function in another namespace, ns doesn’t change to the namespace of the called function, it stays to that of the calling namespace, which.is user in the case of lein bootstrapping your -main.
If you put your (println *ns*) outside of defn, just have it top level below your ns declaration for example, you will see it print test.core.
Finally, no, you should not have an in-ns call inside your -main function.
Is there any reason why it troubles you that your -main function executes within the context of user?
The -main function context is good, I just didn’t understand how it works. I was confused because, looking at the code, it appears that the -main function is inside test.core namespace and not the user namespace.
There is a lot of information in your reply so I am going to spend some time absorbing what you have posted and, if I have any follow up questions, I will post them back on this thread. Thanks.