On Fri, Nov 28, 2008 at 8:33 PM, Vincent Foley <[EMAIL PROTECTED]> wrote: > > I can agree with the multiple-exceptions-in-one-catch, however I don't > think the syntax should be so liberal. It should all be (catch > [Exception+] e body).
The liberal syntax "feature" was more because I didn't know which class to use on the other side of instanceof rather than anything else. If you look at the earlier patch you'll see that I compare the sequence of exceptions against java.util.Collection. I've changed the source to accept only vectors and attached the new patch. The new error message on passing some wrong value as sequence of exceptions is "Expected Exception name or vector of Exception names, got: " + second.getClass() I've tried to follow Rich's indentation style but I could've gotten some things wrong. My emacs settings remove trailing whitespace so there were some extra lines in the diff. I used "svn diff -x -w" to generate the attached diff. Cheers ~vijay > On Nov 28, 1:19 am, "Vijay Lakshminarayanan" <[EMAIL PROTECTED]> > wrote: >> Hi >> >> I'd like to propose a change to Clojure's current try-catch syntax. >> >> Currently the syntax is (copied from clojure.org) >> >> (try expr* catch-clause* finally-clause?) >> catch-clause -> (catch classname name expr*) >> finally-clause -> (finally expr*) >> >> I'd like to propose a change to the catch-clause so that it's possible >> to specify different classnames one of which will be caught and its >> expr evaluated. >> >> It would be something like >> >> (try ... >> (catch SomeException e (println e)) >> (catch (SomeOtherException OrAnotherException) e >> (println "xyz" e)) >> (finally ...)) >> >> In my programming experience I often find that I need to execute the >> same code for a few different exceptions but specialized code for some >> others and rather than duplicate code (that's why we use lisp right? >> no more code duplication!) I thought it would be best that Clojure >> support the same. >> >> I saw that it wasn't possible to modify the try syntax from Clojure >> itself so I modified the clojure.lang.Compiler file to reflect the >> same. >> >> I produced the diff using "svn diff" so patching the same shouldn't be >> too hard, I think. >> >> With the new syntax Exceptions can be specified in a List, Vector or a >> Set but not a map. The exceptions must be specified explicitly as >> they will not be evaluated. So >> >> (try >> (foo) >> (catch [InterruptedException MalformedURLException] e (dont (do-what-i-say >> e))) >> (catch (ArithmeticException NumberFormatException >> NullPointerException) e (do-what-i-mean e)) >> (catch #{RuntimeException} e) >> (catch Exception e (println e))) >> >> are all legal. But >> >> (let [excepts [InterruptedException MalformedURLException]] >> (try >> (foo) >> (catch excepts e (println e)))) >> >> will throw an IllegalArgumentException. >> >> Java7 will probably have syntax similar to the >> abovehttp://tech.puredanger.com/java7#catch >> >> Cheers >> Vijay >> >> Compiler.java.diff >> 7KViewDownload > > > --~--~---------~--~----~------------~-------~--~----~ 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 To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~----------~----~----~----~------~----~------~--~---
Index: src/jvm/clojure/lang/Compiler.java =================================================================== --- src/jvm/clojure/lang/Compiler.java (revision 1127) +++ src/jvm/clojure/lang/Compiler.java (working copy) @@ -1800,9 +1800,22 @@ { if(Util.equal(op, CATCH)) { - Class c = HostExpr.maybeClass(RT.second(f), false); - if(c == null) - throw new IllegalArgumentException("Unable to resolve classname: " + RT.second(f)); + IPersistentVector exceptions = PersistentVector.EMPTY; + Object second = RT.second(f); + + if (second instanceof Symbol) + { + exceptions = exceptions.cons(second); + } + else if (second instanceof IPersistentVector) + { + exceptions = (IPersistentVector) second; + } + else + { + throw new IllegalArgumentException( + "Expected Exception name or vector of Exception names, got: " + second.getClass()); + } if(!(RT.third(f) instanceof Symbol)) throw new IllegalArgumentException( "Bad binding form, expected symbol, got: " + RT.third(f)); @@ -1810,6 +1823,13 @@ if(sym.getNamespace() != null) throw new Exception("Can't bind qualified name:" + sym); + for(ISeq seqEx = exceptions.seq(); seqEx != null; seqEx = seqEx.rest()) + { + Object exception = seqEx.first(); + Class c = HostExpr.maybeClass(exception, false); + if(c == null) + throw new IllegalArgumentException("Unable to resolve classname: " + exception); + IPersistentMap dynamicBindings = RT.map(LOCAL_ENV, LOCAL_ENV.get(), NEXT_LOCAL_NUM, NEXT_LOCAL_NUM.get(), IN_CATCH_FINALLY, RT.T); @@ -1817,7 +1837,7 @@ { Var.pushThreadBindings(dynamicBindings); LocalBinding lb = registerLocal(sym, - (Symbol) (RT.second(f) instanceof Symbol ? RT.second(f) + (Symbol) (exception instanceof Symbol ? exception : null), null); Expr handler = (new BodyExpr.Parser()).parse(context, RT.rest(RT.rest(RT.rest(f)))); catches = catches.cons(new CatchClause(c, lb, handler)); @@ -1828,6 +1848,7 @@ } caught = true; } + } else //finally { if(fs.rest() != null)