So the times when I have the most trouble in Clojure is related to laziness. Using a lot of lazy operations (for, map, etc.) can cause some grief. I was refactoring and added a new parameter to a somewhat common function and didn't catch all the invocations. However, my exception turned up in an entirely different area (one that triggered a cascade of lazy evaluations leading to the exception).
Here, I re-instated the bug and get a large, scary exception: ERROR in (simple-view-and-fragment) (test_is.clj:657) Uncaught exception, not in assertion. expected: nil actual: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.IllegalArgumentException: Wrong number of args passed to: view-manager$fn at clojure.lang.LazySeq.seq (LazySeq.java:46) clojure.lang.RT.seq (RT.java:436) clojure.core/seq (core.clj:103) clojure.core/spread (core.clj:383) clojure.core$apply__3243.doInvoke (core.clj:390) clojure.lang.RestFn.invoke (RestFn.java:428) com.howardlewisship.cascade.view_manager$combine_render_funcs__762$combined__764.invoke (view_manager.clj:52) com.howardlewisship.cascade.view_manager$parse_and_create_view__834$view_equivalent_of_fragment__836.invoke (view_manager.clj:170) com.howardlewisship.cascade.test_views/test_view (test_views.clj:53) com.howardlewisship.cascade.test_views/fn (test_views.clj:60) clojure.contrib.test_is$test_var__318$fn__320.invoke (test_is.clj:655) clojure.contrib.test_is/test_var (test_is.clj:655) clojure.contrib.test_is$test_all_vars__325$fn__327$fn__330.invoke (test_is.clj:670) clojure.contrib.test_is/default_fixture (test_is.clj:628) clojure.contrib.test_is$test_all_vars__325$fn__327.invoke (test_is.clj:670) clojure.contrib.test_is/default_fixture (test_is.clj:628) clojure.contrib.test_is/test_all_vars (test_is.clj:666) clojure.contrib.test_is/test_ns (test_is.clj:688) clojure.core$map__3815$fn__3817.invoke (core.clj:1503) clojure.lang.LazySeq.seq (LazySeq.java:41) clojure.lang.Cons.next (Cons.java:37) clojure.lang.RT.next (RT.java:560) clojure.core/next (core.clj:50) clojure.core$reduce__3319$fn__3322.invoke (core.clj:539) clojure.core/reduce (core.clj:537) clojure.core/reduce (core.clj:531) clojure.core$merge_with__3945.doInvoke (core.clj:1657) clojure.lang.RestFn.applyTo (RestFn.java:144) clojure.core$apply__3243.doInvoke (core.clj:390) clojure.lang.RestFn.invoke (RestFn.java:443) clojure.contrib.test_is$run_tests__339.doInvoke (test_is.clj:701) clojure.lang.RestFn.applyTo (RestFn.java:142) clojure.core$apply__3243.doInvoke (core.clj:390) clojure.lang.RestFn.invoke (RestFn.java:428) user/eval (all_tests.clj:26) clojure.lang.Compiler.eval (Compiler.java:4532) clojure.lang.Compiler.load (Compiler.java:4857) clojure.lang.Compiler.loadFile (Compiler.java:4824) clojure.main/load_script (main.clj:206) clojure.main/script_opt (main.clj:258) clojure.main$main__5888.doInvoke (main.clj:333) clojure.lang.RestFn.invoke (RestFn.java:413) clojure.lang.Var.invoke (Var.java:346) clojure.lang.AFn.applyToHelper (AFn.java:173) clojure.lang.Var.applyTo (Var.java:463) clojure.main.main (main.java:39) Caused by: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.IllegalArgumentException: Wrong number of args passed to: view-manager$fn at clojure.lang.LazySeq.seq (LazySeq.java:46) clojure.lang.RT.seq (RT.java:436) clojure.core/seq (core.clj:103) clojure.core/spread (core.clj:383) clojure.core$apply__3243.doInvoke (core.clj:390) clojure.lang.RestFn.invoke (RestFn.java:428) com.howardlewisship.cascade.view_manager$combine_render_funcs__762$combined__764.invoke (view_manager.clj:52) com.howardlewisship.cascade.view_manager$create_static_element_renderer__823$static_element_renderer__825.invoke (view_manager.clj:147) com.howardlewisship.cascade.view_manager$combine_render_funcs__762$combined__764$iter__765__767$fn__768.invoke (view_manager.clj:53) clojure.lang.LazySeq.seq (LazySeq.java:41) clojure.lang.RT.seq (RT.java:436) clojure.core/seq (core.clj:103) clojure.core/spread (core.clj:383) clojure.core$apply__3243.doInvoke (core.clj:390) clojure.lang.RestFn.invoke (RestFn.java:428) com.howardlewisship.cascade.view_manager$combine_render_funcs__762$combined__764.invoke (view_manager.clj:52) com.howardlewisship.cascade.view_manager$parse_and_create_view__834$view_equivalent_of_fragment__836.invoke (view_manager.clj:170) com.howardlewisship.cascade.test_views/test_view (test_views.clj:53) com.howardlewisship.cascade.test_views/fn (test_views.clj:60) clojure.contrib.test_is$test_var__318$fn__320.invoke (test_is.clj:655) clojure.contrib.test_is/test_var (test_is.clj:655) clojure.contrib.test_is$test_all_vars__325$fn__327$fn__330.invoke (test_is.clj:670) clojure.contrib.test_is/default_fixture (test_is.clj:628) clojure.contrib.test_is$test_all_vars__325$fn__327.invoke (test_is.clj:670) clojure.contrib.test_is/default_fixture (test_is.clj:628) clojure.contrib.test_is/test_all_vars (test_is.clj:666) clojure.contrib.test_is/test_ns (test_is.clj:688) clojure.core$map__3815$fn__3817.invoke (core.clj:1503) clojure.lang.LazySeq.seq (LazySeq.java:41) clojure.lang.Cons.next (Cons.java:37) clojure.lang.RT.next (RT.java:560) clojure.core/next (core.clj:50) clojure.core$reduce__3319$fn__3322.invoke (core.clj:539) clojure.core/reduce (core.clj:537) clojure.core/reduce (core.clj:531) clojure.core$merge_with__3945.doInvoke (core.clj:1657) clojure.lang.RestFn.applyTo (RestFn.java:144) clojure.core$apply__3243.doInvoke (core.clj:390) clojure.lang.RestFn.invoke (RestFn.java:443) clojure.contrib.test_is$run_tests__339.doInvoke (test_is.clj:701) clojure.lang.RestFn.applyTo (RestFn.java:142) clojure.core$apply__3243.doInvoke (core.clj:390) clojure.lang.RestFn.invoke (RestFn.java:428) user/eval (all_tests.clj:26) clojure.lang.Compiler.eval (Compiler.java:4532) clojure.lang.Compiler.load (Compiler.java:4857) clojure.lang.Compiler.loadFile (Compiler.java:4824) clojure.main/load_script (main.clj:206) clojure.main/script_opt (main.clj:258) clojure.main$main__5888.doInvoke (main.clj:333) clojure.lang.RestFn.invoke (RestFn.java:413) clojure.lang.Var.invoke (Var.java:346) clojure.lang.AFn.applyToHelper (AFn.java:173) clojure.lang.Var.applyTo (Var.java:463) clojure.main.main (main.java:39) Caused by: java.lang.RuntimeException: java.lang.IllegalArgumentException: Wrong number of args passed to: view-manager$fn at clojure.lang.LazySeq.seq (LazySeq.java:46) clojure.lang.RT.seq (RT.java:436) clojure.core/seq (core.clj:103) com.howardlewisship.cascade.view_manager$combine_render_funcs__762$combined__764$iter__765__767$fn__768.invoke (view_manager.clj:52) clojure.lang.LazySeq.seq (LazySeq.java:41) clojure.lang.RT.seq (RT.java:436) clojure.core/seq (core.clj:103) clojure.core/spread (core.clj:383) clojure.core$apply__3243.doInvoke (core.clj:390) clojure.lang.RestFn.invoke (RestFn.java:428) com.howardlewisship.cascade.view_manager$combine_render_funcs__762$combined__764.invoke (view_manager.clj:52) com.howardlewisship.cascade.view_manager$create_static_element_renderer__823$static_element_renderer__825.invoke (view_manager.clj:147) com.howardlewisship.cascade.view_manager$combine_render_funcs__762$combined__764$iter__765__767$fn__768.invoke (view_manager.clj:53) clojure.lang.LazySeq.seq (LazySeq.java:41) clojure.lang.RT.seq (RT.java:436) clojure.core/seq (core.clj:103) clojure.core/spread (core.clj:383) clojure.core$apply__3243.doInvoke (core.clj:390) clojure.lang.RestFn.invoke (RestFn.java:428) com.howardlewisship.cascade.view_manager$combine_render_funcs__762$combined__764.invoke (view_manager.clj:52) com.howardlewisship.cascade.view_manager$parse_and_create_view__834$view_equivalent_of_fragment__836.invoke (view_manager.clj:170) com.howardlewisship.cascade.test_views/test_view (test_views.clj:53) com.howardlewisship.cascade.test_views/fn (test_views.clj:60) clojure.contrib.test_is$test_var__318$fn__320.invoke (test_is.clj:655) clojure.contrib.test_is/test_var (test_is.clj:655) clojure.contrib.test_is$test_all_vars__325$fn__327$fn__330.invoke (test_is.clj:670) clojure.contrib.test_is/default_fixture (test_is.clj:628) clojure.contrib.test_is$test_all_vars__325$fn__327.invoke (test_is.clj:670) clojure.contrib.test_is/default_fixture (test_is.clj:628) clojure.contrib.test_is/test_all_vars (test_is.clj:666) clojure.contrib.test_is/test_ns (test_is.clj:688) clojure.core$map__3815$fn__3817.invoke (core.clj:1503) clojure.lang.LazySeq.seq (LazySeq.java:41) clojure.lang.Cons.next (Cons.java:37) clojure.lang.RT.next (RT.java:560) clojure.core/next (core.clj:50) clojure.core$reduce__3319$fn__3322.invoke (core.clj:539) clojure.core/reduce (core.clj:537) clojure.core/reduce (core.clj:531) clojure.core$merge_with__3945.doInvoke (core.clj:1657) clojure.lang.RestFn.applyTo (RestFn.java:144) clojure.core$apply__3243.doInvoke (core.clj:390) clojure.lang.RestFn.invoke (RestFn.java:443) clojure.contrib.test_is$run_tests__339.doInvoke (test_is.clj:701) clojure.lang.RestFn.applyTo (RestFn.java:142) clojure.core$apply__3243.doInvoke (core.clj:390) clojure.lang.RestFn.invoke (RestFn.java:428) user/eval (all_tests.clj:26) clojure.lang.Compiler.eval (Compiler.java:4532) clojure.lang.Compiler.load (Compiler.java:4857) clojure.lang.Compiler.loadFile (Compiler.java:4824) clojure.main/load_script (main.clj:206) clojure.main/script_opt (main.clj:258) clojure.main$main__5888.doInvoke (main.clj:333) clojure.lang.RestFn.invoke (RestFn.java:413) clojure.lang.Var.invoke (Var.java:346) clojure.lang.AFn.applyToHelper (AFn.java:173) clojure.lang.Var.applyTo (Var.java:463) clojure.main.main (main.java:39) Caused by: java.lang.IllegalArgumentException: Wrong number of args passed to: view-manager$fn at clojure.lang.AFn.throwArity (AFn.java:449) clojure.lang.AFn.invoke (AFn.java:52) clojure.lang.MultiFn.invoke (MultiFn.java:157) clojure.core$map__3815$fn__3817.invoke (core.clj:1503) clojure.lang.LazySeq.seq (LazySeq.java:41) clojure.lang.RT.seq (RT.java:436) clojure.core/seq (core.clj:103) com.howardlewisship.cascade.view_manager$combine_render_funcs__762$combined__764$iter__765__767$fn__768.invoke (view_manager.clj:52) clojure.lang.LazySeq.seq (LazySeq.java:41) clojure.lang.RT.seq (RT.java:436) clojure.core/seq (core.clj:103) clojure.core/spread (core.clj:383) clojure.core$apply__3243.doInvoke (core.clj:390) clojure.lang.RestFn.invoke (RestFn.java:428) com.howardlewisship.cascade.view_manager$combine_render_funcs__762$combined__764.invoke (view_manager.clj:52) com.howardlewisship.cascade.view_manager$create_static_element_renderer__823$static_element_renderer__825.invoke (view_manager.clj:147) com.howardlewisship.cascade.view_manager$combine_render_funcs__762$combined__764$iter__765__767$fn__768.invoke (view_manager.clj:53) clojure.lang.LazySeq.seq (LazySeq.java:41) clojure.lang.RT.seq (RT.java:436) clojure.core/seq (core.clj:103) clojure.core/spread (core.clj:383) clojure.core$apply__3243.doInvoke (core.clj:390) clojure.lang.RestFn.invoke (RestFn.java:428) com.howardlewisship.cascade.view_manager$combine_render_funcs__762$combined__764.invoke (view_manager.clj:52) com.howardlewisship.cascade.view_manager$parse_and_create_view__834$view_equivalent_of_fragment__836.invoke (view_manager.clj:170) com.howardlewisship.cascade.test_views/test_view (test_views.clj:53) com.howardlewisship.cascade.test_views/fn (test_views.clj:60) clojure.contrib.test_is$test_var__318$fn__320.invoke (test_is.clj:655) clojure.contrib.test_is/test_var (test_is.clj:655) clojure.contrib.test_is$test_all_vars__325$fn__327$fn__330.invoke (test_is.clj:670) clojure.contrib.test_is/default_fixture (test_is.clj:628) clojure.contrib.test_is$test_all_vars__325$fn__327.invoke (test_is.clj:670) clojure.contrib.test_is/default_fixture (test_is.clj:628) clojure.contrib.test_is/test_all_vars (test_is.clj:666) clojure.contrib.test_is/test_ns (test_is.clj:688) clojure.core$map__3815$fn__3817.invoke (core.clj:1503) clojure.lang.LazySeq.seq (LazySeq.java:41) clojure.lang.Cons.next (Cons.java:37) clojure.lang.RT.next (RT.java:560) clojure.core/next (core.clj:50) clojure.core$reduce__3319$fn__3322.invoke (core.clj:539) clojure.core/reduce (core.clj:537) clojure.core/reduce (core.clj:531) clojure.core$merge_with__3945.doInvoke (core.clj:1657) clojure.lang.RestFn.applyTo (RestFn.java:144) clojure.core$apply__3243.doInvoke (core.clj:390) clojure.lang.RestFn.invoke (RestFn.java:443) clojure.contrib.test_is$run_tests__339.doInvoke (test_is.clj:701) clojure.lang.RestFn.applyTo (RestFn.java:142) clojure.core$apply__3243.doInvoke (core.clj:390) clojure.lang.RestFn.invoke (RestFn.java:428) user/eval (all_tests.clj:26) clojure.lang.Compiler.eval (Compiler.java:4532) clojure.lang.Compiler.load (Compiler.java:4857) clojure.lang.Compiler.loadFile (Compiler.java:4824) clojure.main/load_script (main.clj:206) clojure.main/script_opt (main.clj:258) clojure.main$main__5888.doInvoke (main.clj:333) clojure.lang.RestFn.invoke (RestFn.java:413) clojure.lang.Var.invoke (Var.java:346) clojure.lang.AFn.applyToHelper (AFn.java:173) clojure.lang.Var.applyTo (Var.java:463) clojure.main.main (main.java:39) Can you tell where the error is? The stack trace is misleading; it is a problem in (create-static-element-renderer) but on line 133 (not the 147 listed in the stack trace). (defn- create-static-element-renderer [namespace element-node] (let [body (element-node :body) token (element-node :token) element-uri (token :ns-uri) element-name (token :tag) element-ns-uri-to-prefix (element-node :ns-uri-to-prefix) body-as-funcs (map to-fragment-fn body) ; LINE 133 body-combined (combine-render-funcs body-as-funcs) attributes (construct-attributes (element-node :attributes))] (fn static-element-renderer [env params] [(struct-map dom-node :type :element :ns-uri element-uri :ns-uri-to-prefix (remove-cascade-namespaces element-ns-uri-to-prefix) :name element-name ; currently assuming that attributes are "static" but ; that will change ... though we should seperate "static" from "dynamic" :attributes attributes ; TODO: there might be a way to identify that a static element has only static ; content, in which case the body can itself be computed statically :content (body-combined env params))]))) ; LINE 147 The fix was to replace line 133 with: body-as-funcs (map (partial to-fragment-fn namespace) body) I'm not sure what can be done about this kind of problem. The laziness is wonderful until it breaks ... here's an area where Haskell would have been able to identify the incorrect call via static analysis. Tapestry has some similar problems, based on how user code is so intermixed with framework code; it does a lot of work to identify why a given method is being invoked ... you get a stack of components that are rendering (which leads to what component class methods are being invoked); there's a similar concept in the IoC container to trace what objects are being instantiated, which methods or contructors are being invoked, and parameter values being calculated (this latter case uses a lot of Thread Locals and is inefficient and ugly). Again, I'm not sure what the solution is or what the implementation would look like, but I'd love it if Clojure could relate back to me, when an exception occurred, what lazy operations were taking place that caused the bad code to be invoked. -- Howard M. Lewis Ship Creator of Apache Tapestry Director of Open Source Technology at Formos --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---