0

It should be fairly apparent to anyone that has ever touched a compiler that good compiler messages aid debugging time, this is also clear in various journals on the subject. This is often the reason why a lot of effort is spent on integrating error intelligence with the IDE (E.g.: Visual Studio and Resharper, Delphi Error Insight, Oxygene Inline Errors) making it much easier to detect common compiler error causing errors.

Whilst I’ve recently enjoyed learning Clojure a lot, one compiler that I’ve found to be particularly lacking is the Clojure compiler itself, often spitting out cryptic error messages. Often requiring you to check out the clojure source to identify what the method appearing in the stack trace actually does to give some clue as to what might be causing the error. When a compiler is still young, one shouldn’t expect everything out of the box but slightly less cryptic messages would save valuable developer time.

To save anyone spending as long as I did on an error like this, my compiler stack trace looked like the below:

Compiling my-app.core
Exception in thread "main" java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol, compiling:(controller.clj:1)
	at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3342)
	at clojure.lang.Compiler.compile1(Compiler.java:6985)
	at clojure.lang.Compiler.compile1(Compiler.java:6975)
	at clojure.lang.Compiler.compile(Compiler.java:7046)
	at clojure.lang.RT.compile(RT.java:385)
	at clojure.lang.RT.load(RT.java:425)
	at clojure.lang.RT.load(RT.java:398)
	at clojure.core$load$fn__4610.invoke(core.clj:5386)
	at clojure.core$load.doInvoke(core.clj:5385)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at clojure.core$load_one.invoke(core.clj:5200)
	at clojure.core$load_lib.doInvoke(core.clj:5237)
	at clojure.lang.RestFn.applyTo(RestFn.java:142)
	at clojure.core$apply.invoke(core.clj:602)
	at clojure.core$load_libs.doInvoke(core.clj:5271)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.core$apply.invoke(core.clj:602)
	at clojure.core$require.doInvoke(core.clj:5352)
	at clojure.lang.RestFn.invoke(RestFn.java:1289)
	at my-app.routes$loading__4505__auto__.invoke(routes.clj:1)
	at clojure.lang.AFn.applyToHelper(AFn.java:159)
	at clojure.lang.AFn.applyTo(AFn.java:151)
	at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3337)
	at clojure.lang.Compiler.compile1(Compiler.java:6985)
	at clojure.lang.Compiler.compile1(Compiler.java:6975)
	at clojure.lang.Compiler.compile(Compiler.java:7046)
	at clojure.lang.RT.compile(RT.java:385)
	at clojure.lang.RT.load(RT.java:425)
	at clojure.lang.RT.load(RT.java:398)
	at clojure.core$load$fn__4610.invoke(core.clj:5386)
	at clojure.core$load.doInvoke(core.clj:5385)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at clojure.core$load_one.invoke(core.clj:5200)
	at clojure.core$load_lib.doInvoke(core.clj:5237)
	at clojure.lang.RestFn.applyTo(RestFn.java:142)
	at clojure.core$apply.invoke(core.clj:602)
	at clojure.core$load_libs.doInvoke(core.clj:5271)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.core$apply.invoke(core.clj:604)
	at clojure.core$use.doInvoke(core.clj:5363)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at my-app.core$loading__4505__auto__.invoke(core.clj:1)
	at clojure.lang.AFn.applyToHelper(AFn.java:159)
	at clojure.lang.AFn.applyTo(AFn.java:151)
	at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3337)
	at clojure.lang.Compiler.compile1(Compiler.java:6985)
	at clojure.lang.Compiler.compile1(Compiler.java:6975)
	at clojure.lang.Compiler.compile(Compiler.java:7046)
	at clojure.lang.RT.compile(RT.java:385)
	at clojure.lang.RT.load(RT.java:425)
	at clojure.lang.RT.load(RT.java:398)
	at clojure.core$load$fn__4610.invoke(core.clj:5386)
	at clojure.core$load.doInvoke(core.clj:5385)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at clojure.core$load_one.invoke(core.clj:5200)
	at clojure.core$compile$fn__4615.invoke(core.clj:5397)
	at clojure.core$compile.invoke(core.clj:5396)
	at user$eval7.invoke(NO_SOURCE_FILE:1)
	at clojure.lang.Compiler.eval(Compiler.java:6465)
	at clojure.lang.Compiler.eval(Compiler.java:6455)
	at clojure.lang.Compiler.eval(Compiler.java:6431)
	at clojure.core$eval.invoke(core.clj:2795)
	at clojure.main$eval_opt.invoke(main.clj:296)
	at clojure.main$initialize.invoke(main.clj:315)
	at clojure.main$null_opt.invoke(main.clj:348)
	at clojure.main$main.doInvoke(main.clj:426)
	at clojure.lang.RestFn.invoke(RestFn.java:421)
	at clojure.lang.Var.invoke(Var.java:405)
	at clojure.lang.AFn.applyToHelper(AFn.java:163)
	at clojure.lang.Var.applyTo(Var.java:518)
	at clojure.main.main(main.java:37)
Caused by: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol
	at clojure.lang.RT.seqFrom(RT.java:487)
	at clojure.lang.RT.seq(RT.java:468)
	at clojure.lang.RT.first(RT.java:560)
	at clojure.core$first.invoke(core.clj:55)
	at clojure.core$map$fn__3811.invoke(core.clj:2432)
	at clojure.lang.LazySeq.sval(LazySeq.java:42)
	at clojure.lang.LazySeq.seq(LazySeq.java:60)
	at clojure.lang.RT.seq(RT.java:466)
	at clojure.core$seq.invoke(core.clj:133)
	at clojure.core$filter$fn__3830.invoke(core.clj:2468)
	at clojure.lang.LazySeq.sval(LazySeq.java:42)
	at clojure.lang.LazySeq.seq(LazySeq.java:60)
	at clojure.lang.RT.seq(RT.java:466)
	at clojure.core$seq.invoke(core.clj:133)
	at clojure.core$assert_valid_fdecl.invoke(core.clj:6464)
	at clojure.core$sigs.invoke(core.clj:220)
	at clojure.core$defn.doInvoke(core.clj:293)
	at clojure.lang.RestFn.invoke(RestFn.java:525)
	at clojure.lang.Var.invoke(Var.java:421)
	at clojure.lang.AFn.applyToHelper(AFn.java:185)
	at clojure.lang.Var.applyTo(Var.java:518)
	at clojure.lang.Compiler.macroexpand1(Compiler.java:6320)
	at clojure.lang.Compiler.macroexpand(Compiler.java:6381)
	at clojure.lang.Compiler.compile1(Compiler.java:6970)
	at clojure.lang.Compiler.compile(Compiler.java:7046)
	at clojure.lang.RT.compile(RT.java:385)
	at clojure.lang.RT.load(RT.java:425)
	at clojure.lang.RT.load(RT.java:398)
	at clojure.core$load$fn__4610.invoke(core.clj:5386)
	at clojure.core$load.doInvoke(core.clj:5385)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at clojure.core$load_one.invoke(core.clj:5200)
	at clojure.core$load_lib.doInvoke(core.clj:5237)
	at clojure.lang.RestFn.applyTo(RestFn.java:142)
	at clojure.core$apply.invoke(core.clj:602)
	at clojure.core$load_libs.doInvoke(core.clj:5271)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.core$apply.invoke(core.clj:604)
	at clojure.core$use.doInvoke(core.clj:5363)
	at clojure.lang.RestFn.invoke(RestFn.java:457)
	at my-app.controller$loading__4505__auto__.invoke(controller.clj:1)
	at clojure.lang.AFn.applyToHelper(AFn.java:159)
	at clojure.lang.AFn.applyTo(AFn.java:151)
	at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3337)
	... 70 more
Compilation failed: Subprocess failed

After asking around in #clojure on Freenode, I got some excellent advice from amalloy, who suggested that it was related to a mis-declared defn. Despite looking through the two files mentioned in the stacktrace above and failing to find anything, I eventually rolled back through my git revision log until I found that there was a defn in another file in the project which was require‘d by the routes.clj file mentioned in the stack trace above, which looked like:

 
(defn my-descriptive-function-name param1 [param2]
  (...)
)

Where it should have looked like this:

 
(defn my-descriptive-function-name [param1 param2]
  (...)
)

Hope that helps someone else get to the bottom of at least one cryptic message!

Tags: ,

Leave a Comment