require namespace implicitly
Description
Environment
Activity
Rich Hickey June 22, 2011 at 12:41 AM
This is not a good idea, for many reasons, the simplest of which is: it makes loading a side effect of calling a function in a module. Since loading can have arbitrary effects, it shouldn't be implicit. This isn't warranted by the meager benefits it might provide.
Paul Stadig June 10, 2011 at 9:00 PM
I think it gets emitted in the middle of a function, just like would happen now if you do (require 'clojure.set) (clojure.set/union ...)
Is there a benefit to having it emit separately like an ns form? Isn't the ns form just a macro that turns into calls to (require ...) which happen to be at the top of a file because that's where the ns form is?
Kevin Downey June 10, 2011 at 8:27 PM
the patch doesn't actually cause code to load the required namespaces to be generated. it only loads the required namespaces during compilation, which is why it breaks aot. once you get into code generation for aot it gets complicated, where does the generated code go? do we want to try and emit it separately like the requires from an ns form or does it get emitted in the middle of the particular function being compiled. I think the first approach is desirable from a stand point of correctness, but carries with it a load of complexity.
Paul Stadig June 10, 2011 at 8:21 PM
So I've been told that my tongue-in-cheek may not have translated well, but that was the intent. I apologize if that was the case.
My point is just to draw attention to this ticket again. It was discussed on the ML with several +1's and has been mentioned again in chat. I don't think any of the objections that Stuart Sierra raised are particularly relevant to the question of autoloading the namespace of a fully qualified var.
Has anyone tried the patch? Kevin Downey seems to think it will not work in the context of AOT.
Do we need a new patch?
Kevin Downey June 10, 2011 at 8:07 PM
I have serious reservations about the complexity this will add to the compiler. the current patch is no good, it will break for aot compilation.
Referencing a function with a fully-qualified namespace should work without first using require or use, similar to how a fully-qualified java class can be used without importing it.
It's a small change in Compiler that tries to call (require x) if the fully qualified classname is not found. This should give priority to the java class, which protects backwards compatibility. There is no runtime performance impact, only compile time (the first time the namespace is seen). The fact that code (the namespace) is loaded during compilation of a form is no different than loading code to look up a java class.
This makes it easier to write quick scripts as in the example below, also to use one-liners in the repl or ad hoc in code.
For example: java -cp src/clj/:classes clojure.main -e "(clojure.set/union #{1} #{2})"
Currently on master, this produces: Exception in thread "main" java.lang.ClassNotFoundException: clojure.set
but this works: java -cp src/clj/:classes clojure.main -e "(require 'clojure.set) (clojure.set/union #{1} #{2})"
Obviously, (use) would make the code shorter, but my goal is to make it implicit.
Discussion: http://groups.google.com/group/clojure-dev/t/69823ce63dd94a0c