Hi all

I've been thinking about how long tracebacks get for pure Clojure errors, 
and it would be really nice if we could hide the Java traceback from the 
compiler when it's not relevant. When there's no Java interop, it's not 
useful. I can't see any case where we want the tracebacks from the compiler 
referencing clojure.core.

I threw together a patch -- I'm sure a seasoned Java developer would find a 
nicer way to do this.

Here's how the tracebacks look at the moment on trunk:

$ more dodgy-map.clj
(defn dodgy-map []
  {:1 :2 :3})
$ java -cp target/clojure-1.5.0-master-SNAPSHOT.jar clojure.main 
dodgy-map.clj
Exception in thread "main" java.lang.RuntimeException: Map literal must 
contain an even number of forms, 
compiling:(/home/wilfred/src/clojure/dodgy-map.clj:2:13)
    at clojure.lang.Compiler.load(Compiler.java:7069)
    at clojure.lang.Compiler.loadFile(Compiler.java:7019)
    at clojure.main$load_script.invoke(main.clj:286)
    at clojure.main$script_opt.invoke(main.clj:348)
    at clojure.main$main$fn__6676.invoke(main.clj:432)
    at clojure.main$main.doInvoke(main.clj:429)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.lang.Var.invoke(Var.java:415)
    at clojure.lang.AFn.applyToHelper(AFn.java:161)
    at clojure.lang.Var.applyTo(Var.java:532)
    at clojure.main.main(main.java:37)
Caused by: java.lang.RuntimeException: Map literal must contain an even 
number of forms
    at clojure.lang.Util.runtimeException(Util.java:219)
    at clojure.lang.LispReader$MapReader.invoke(LispReader.java:1090)
    at clojure.lang.LispReader.readDelimitedList(LispReader.java:1145)
    at clojure.lang.LispReader$ListReader.invoke(LispReader.java:979)
    at clojure.lang.LispReader.read(LispReader.java:182)
    at clojure.lang.Compiler.load(Compiler.java:7057)
    ... 10 more

If I change src/jvm/clojure/main.java to:

public static void main(String[] args) {
    REQUIRE.invoke(CLOJURE_MAIN);
    try {
        MAIN.applyTo(RT.seq(args));
    } catch (Compiler.CompilerException e) {
        System.out.println(e.toString());
    }
}

Then my traceback is simplified to:

$ java -cp target/clojure-1.5.0-master-SNAPSHOT.jar clojure.main 
dodgy-map.clj
java.lang.RuntimeException: Map literal must contain an even number of 
forms, compiling:(/home/wilfred/src/clojure/dodgy-map.clj:2:13)

This also means that name errors have shorter tracebacks:

$ more i-dont-exist.clj
(defn no-such-variable []
  i-dont-exist)

$ java -cp target/clojure-1.5.0-master-SNAPSHOT.jar clojure.main 
i-dont-exist.clj
java.lang.RuntimeException: Unable to resolve symbol: i-dont-exist in this 
context, compiling:(/home/wilfred/src/clojure/i-dont-exist.clj:1:1)

Of course, there's huge scope for improvement. The reference to 
"java.lang.RuntimeException" isn't useful. It would be nice to split 
CompilerException into more specific exception classes (SyntaxError, 
NameError etc) so we can print different errors at the top level. This 
simple patch also changes the exit code of the compiler, which is 
undesirable. Finally, it'd need some new unit tests.

Anyway, is this something that is worth opening an issue for? I'd love to 
hear your thoughts.

Wilfred

-- 
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
Note that posts from new members are moderated - please be patient with your 
first post.
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

Reply via email to