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)

Reply via email to