Sometimes I want to do the same thing for multiple classes of
exceptions without writing very similar catch clauses repeatedly, so I
wrote a macro:

(defmacro try*
  "Exactly like try, except that catch statements can contain a
   sequence of exception-types which should all be handled in the same
   way. E.g.:

   (try* expr1 expr2
      (catch ArithmeticException a-exc ...)
      (catch [Exception AssertionError] e ...)
      (finally ...)"
  [& exprs]
  (letfn [(is-multi-catch? [expr] (sequential? (second expr)))
          (expand-catches [expr] (map (fn [exn-type] (list* 'catch
exn-type (drop 2 expr))) (second expr)))
          (is-postlude? [expr] (and (list? expr) (#{'finally 'catch}
(first expr))))]
    (let [[exprs postlude] (split-with (complement is-postlude?) exprs)
          [catches finally] (split-with (comp #{'catch} first) postlude)
          catches (mapcat #(if (is-multi-catch? %) (expand-catches %)
[%]) catches)]
     ;; kick errors down to core try
      `(try ~@exprs
            ~@catches
            ~@finally))))

This seems to work fine.

But it *doesn't* work inside a different macro:

user> (defmacro g [& forms] `(try* ~@forms (catch [Exception
AssertionError] e# 6)))
#'user/g
user> (g  2 3)
; Evaluation aborted
with the error: Unable to resolve classname: [java.lang.Exception
java.lang.AssertionError]

These macroexpansions are as expected:

user> (macroexpand-1 '(g 2 3))
(user/try* 2 3 (catch [java.lang.Exception java.lang.AssertionError]
e__45530__auto__ 6))
user> (macroexpand-1 '(user/try* 2 3 (catch [java.lang.Exception
java.lang.AssertionError] e__45530__auto__ 6)))
(try 2 3 (catch java.lang.Exception e__45530__auto__ 6) (catch
java.lang.AssertionError e__45530__auto__ 6))

But the second one here (the first is identical to the above) is not:

user> (macroexpand-1 '(g 2 3))
(user/try* 2 3 (catch [java.lang.Exception java.lang.AssertionError]
e__45530__auto__ 6))
user> (macroexpand-1 *1)
(try 2 3 (catch [java.lang.Exception java.lang.AssertionError]
e__45530__auto__ 6))

What's going on? Where'd my try* go?

-- 
Ben Wolfson
"Human kind has used its intelligence to vary the flavour of drinks,
which may be sweet, aromatic, fermented or spirit-based. ... Family
and social life also offer numerous other occasions to consume drinks
for pleasure." [Larousse, "Drink" entry]

-- 
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