On Apr 17, 2009, at 11:40 PM, Stuart Sierra wrote:
On Apr 17, 11:23 pm, "Stephen C. Gilardi" <squee...@mac.com> wrote:I suggest using a "-main" function for this purpose. Then with (ns ... (:gen-class)) you can generate a static Java class with same behavior.And if the :gen-class clause renamed main would the main function for this namespace be that named function?Sure. This even suggests a process: To "execute" a namespace, first compile it, then invoke the main() method of the generated class. We might try to simplify the compile path stuff first.
One of the main points of this is for it to work if you don't compile it. We've had the "compile it" solution for a while and I've used it and like it. But the current way of running scripts is very different and I hope to change that. Launching through clojure.main or through java directly ought to be very very similar.
There's currently no way to return a "status" value from an argument with that signature without using System/exit which has the unfortunate side effect of also shutting down the JVM.True, but the Clojure function can still return a value, if it's being called interactively. And if it's not being called interactively, it's ok to use System/exit. I frequently do this: (ns my.cool.namespace (:gen-class)) (defn run [args] ... execution code goes here... ... return an integer ...) (defn -main [& args] (System/exit (run args)))
I think this demonstrates why your "run" function, and not your "- main" function is the entry point at the appropriate level for what I'm after in my proposal. I'm proposing that the namespace be executable from the repl *or any other Clojure code* via run, *and* from the java command line via the namespace name being the first argument to clojure.main.
I think not requiring that a namespace be compiled for this to work is pretty key.
From the REPL, I call "run". From the command line, I call "java my.cool.namespace", which invokes "-main", which calls "run". Different routes, same result.
Right. With my proposal it would be from the repl: user=> (run my-ns "arg1" "arg2") 0 user=> or from the command line: % java -cp clojure.jar:. clojure.main my-ns arg1 arg2 % echo $? 0 %In fact, with an easily found, well-defined "run" function (which I think should *always* be specified by a :run clause in the namespace's ns form), we could even default the definition of -main to be the one you use:
(defn -main [& args] (System/exit (run args)))
(with the "run" function named as specified for this namespac) --Steve
smime.p7s
Description: S/MIME cryptographic signature