Hi, This indeed seems like an improvement to me, since from then there will be no excuse to have namespaces doing time or resource consuming operations (I'm thinking about those scripts that automatically load GUIs, ...) at load (and even compile *ouch*) time.
* Concerning the name of the keyword, may I suggest to use :main instead of :run ? The word "main" is the convention in the java world for referencing a candidate class for being the Main class of the application (Main is used in MANIFESTs , in naming the public static void main(String args[]) ...) ? * We could make this :main keyword play well with the :gen-class directive if it is present in the namespace declaration : Examples of use: (ns (:main)) ; there could be a default name for the function (if :main is present of course). This could be (-main) to offer a smooth migration if later on the ns is gen-classed (ns (:main) (:gen-class (:prefix "foo")) ; here :main would stay "aligned" with :gen-class by default (DRY principle) and the main function of the ns would be the main function of the class generated : (foo-main) (ns (:main ns-main-function)) ; the main function for the ns is ns-main-function. (ns (:main ns-main-function) (:gen-class)) ; here since :main explicit defines a name, it is intentionally not aligned with the generated class' main function * Concerning the execution : it could be interesting, then, to be able to launch such a script as one would launch a plain old java executable : java -cpclojure.jar:classes/:src/ my.ns Considering this last proposition, this would imply to even more closely couple the use of the new :main keyword with the :gen-class directive. Indeed, this would imply that if :main is used alone (without :gen-class at all), the namespace would be compiled into a file. (And then, the value for the function name better be just always aligned with the :gen-class'). Though, I'm not sure whether this last step is a good idea, since it forces either to always compile namespaces that would be auto-executable, or either to "auto-compile" the ns if the :main keyword is found (and I don't like the idea of compiling ahead of time in the background, since the classes/ directory may well not have been placed in the classpath by the user). What do you think about that ? My 0,02 €, -- Laurent 2009/4/18 Stephen C. Gilardi <squee...@mac.com> > > On Apr 17, 2009, at 5:21 PM, Tom Faulhaber wrote: > > > I'd also like to see a little more focus on the perl/python/ruby > > equivalence from a newbie perspective. That is, more clarity around > > startup, script execution (including having an equivalent to python's > > "if __name__ == '__main__':" construct), class path management, etc. > > I know that this is one area where being in the JVM ecosystem makes > > our life worse rather than better, but approaching Clojure is still a > > bit daunting compared to these other languages. > > I have a proposal for a standard way to make a namespace "executable" > and to invoke it as a program/script. > > The basic idea is to mark each namespace intended to be run as > "program" such that its entry point can be found and to provide > support for calling that entry point easily. > > An outline: > > - add a key to the "ns" form to specify, as a symbol, the name of > a function to be called when the namespace is "invoked" as a script. > > - I propose ":run" (with no default so no namespace is ever > accidentally executable.) > > - If provided, the :run value in the ns form is stored as > the :run value in the namespace's metadata. > > - The run function should > > - accept/expect Strings as arguments > > - it may accept any number of Strings using normal > Clojure arity rules. > > - return an Integer > > - zero indicates success > > - non-zero indicates (some kind of) failure > > - error codes should be chosen and documented by > the namespace author > > - add a function to clojure.core to run an executable namespace: > > - (run ns-name arg*) > > - requires the namespace > > - retrieves the namespace's :run value and resolves it to > a var in the namespace. > > - calls that function via: > (apply the-run-func args) > > - returns the integer that the-run-func returns > > - add support to clojure-main to handle a namespace name in > "script position" by: > > - calling "run" on it, passing *command-line-args* in for the > args. > > - returning the status value to the OS via Java's System/exit > facility > > This would be a change away from the current handling of scripts which > simply loads them, expecting them to do their operation at load time. > It also requires the resource (file) that contains the script be in > classpath. (Though that's easy to accomplish by adding "<path-to-the- > script>" to classpath.) > > With this method, we have a new standard way to invoke a script, and > the scripts we load this way are "clean" in the sense that they don't > run arbitrary code while loading. (They can, of course, run arbitrary > code during macro expansion but it's still a good idea not to have > bits of executable code laying around being loaded when the > namespace's definition is loaded.) > > A clear separation for scripts between load time and run time is a win. > > Also with this method, we can treat (specially marked) namespaces that > have already been loaded into Clojure as runnable entities (albeit > with a rather restricted interface for arguments and return values). > We can invoke them from other Clojure code as we would in a shell > script, but without involving the OS at all. > > Via string arguments, these Clojure scripts could also indicate/react- > to a desire to use *in* *out* and *err* to communicate as > corresponding UNIX tools would when run by the shell. > > People who want to "run code from a file" will still be able to do so > by using "load", but that would no longer be the supported mechanism > for writing/using/invoking Clojure scripts. > > Thoughts? > > --Steve > > --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~----------~----~----~----~------~----~------~--~---