<div dir="ltr">Sean, it would, but then we get into the whole &quot;Well, this throws ChangePictureError, which could be a NetworkException, or a ParseException&quot; thing...sound at all familiar? &quot;Well, this throws IOException, which could be FileNotFoundException, MalformedURLException, ProtocolException, ObjectStreamException, UnsupportedEncodingException, SSLException...&quot;. I guess I am just saying there is still some work to be done with regards to wrapping and rethrowing exceptions.<div><br></div><div>How would you catch a Parse with statusCode==401 in a catch statement?</div></div><br><div class="gmail_quote"><div dir="ltr">On Fri, Dec 18, 2015 at 1:49 PM Sean Heber &lt;<a href="mailto:sean@fifthace.com">sean@fifthace.com</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I may just not be understanding what this is trying to solve, but the following would work too, wouldn’t it?<br>
<br>
enum NetworkException {<br>
  case NoInternetError, SecurityError<br>
}<br>
<br>
enum ParseException {<br>
  case FailedResponse(statusCode: Int)<br>
  case EmptyResponse<br>
  case MissingField(fieldName: String)<br>
}<br>
<br>
enum ChangePictureError {<br>
  case Network(NetworkException)<br>
  case Parse(ParseException)<br>
  etc..<br>
}<br>
<br>
l8r<br>
Sean<br>
<br>
<br>
&gt; On Dec 18, 2015, at 12:42 PM, T.J. Usiyan via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br>
&gt;<br>
&gt; I think that you can accomplish this right now if you make your backing enum literal convertible. String literal would have been the better choice in the example below but I was feeling lazy.<br>
&gt;<br>
&gt; public enum MyLibError: ErrorType, IntegerLiteralConvertible {<br>
&gt;     case FileNotFound<br>
&gt;     case UnexpectedEOF<br>
&gt;     case PermissionDenied<br>
&gt;     // ... 300 cases later<br>
&gt;     case FluxCapacitorFailure<br>
&gt;     case SplineReticulationError<br>
&gt;     case UnknownError<br>
&gt;<br>
&gt;     public init(integerLiteral value: Int) {<br>
&gt;         switch value {<br>
&gt;         case 0:<br>
&gt;             self = .FileNotFound<br>
&gt;         case 1:<br>
&gt;             self = .UnexpectedEOF<br>
&gt;         case 2:<br>
&gt;             self = .PermissionDenied<br>
&gt;         case 3:<br>
&gt;             self = .FluxCapacitorFailure<br>
&gt;         case 4:<br>
&gt;             self = .SplineReticulationError<br>
&gt;         default:<br>
&gt;             self = .UnknownError<br>
&gt;         }<br>
&gt;     }<br>
&gt; }<br>
&gt;<br>
&gt; enum FileSystemError: MyLibError {<br>
&gt;     case FileNotFound = 0<br>
&gt;     case UnexpectedEOF = 1<br>
&gt;     case PermissionDenied = 2<br>
&gt; }<br>
&gt;<br>
&gt; On Fri, Dec 18, 2015 at 12:34 PM, Dennis Lysenko via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br>
&gt; Sorry, I got a bit too excited and skimmed over the most important part of the idea. So this is a special type of enum declaration in which you cannot declare any new enum members. I personally have not seen a use for this in my code but I would love to hear others&#39; response to it. It is a very interesting idea though.<br>
&gt;<br>
&gt; I&#39;m going to go out on a limb with an idea that is in the same vein as this one: What if we favored composition over inheritance here, and made it so that you could transparently refer to members of other enums *without* having another enum as a backing type?<br>
&gt;<br>
&gt; e.g., you have:<br>
&gt; enum NetworkException {<br>
&gt;   case NoInternetError, SecurityError<br>
&gt; }<br>
&gt;<br>
&gt; enum ParseException {<br>
&gt;   case FailedResponse(statusCode: Int)<br>
&gt;   case EmptyResponse<br>
&gt;   case MissingField(fieldName: String)<br>
&gt; }<br>
&gt;<br>
&gt; As two general classes of errors. But for a full API call wrapper, you might want an error class that composes the two, so that when calling the API call from your UI code, you can display a &quot;please check your connection&quot; message for NoInternetError, a &quot;Please log in&quot; error for FailedResponse with statusCode=401, or a &quot;server error&quot; message for any of the rest.<br>
&gt;<br>
&gt; I wonder how do you and others feel about that use-case? I have certainly seen it come up a lot in real-world projects that require resilient UI interactions with nontrivial networking operations.<br>
&gt;<br>
&gt; Here are some quick code samples off the top of my head for how we might go about this (let&#39;s say the API operation is &quot;change profile picture&quot;:<br>
&gt;<br>
&gt; enum ChangePictureError {<br>
&gt;   include NetworkException<br>
&gt;   include ParseException<br>
&gt;   case PictureTooLarge<br>
&gt; }<br>
&gt;<br>
&gt; or<br>
&gt;<br>
&gt; enum ChangePictureError {<br>
&gt;   compose NetworkException.NoInternetError<br>
&gt;   compose ParseException.EmptyResponse<br>
&gt;   compose ParseException.FailedResponse(statusCode: Int)<br>
&gt;   case PictureTooLarge<br>
&gt; }<br>
&gt;<br>
&gt; Not a proposal by any stretch of the imagination, just a potential direction inspired by your idea, Felix.<br>
&gt;<br>
&gt;<br>
&gt; On Fri, Dec 18, 2015 at 12:21 PM Dennis Lysenko &lt;<a href="mailto:dennis.s.lysenko@gmail.com" target="_blank">dennis.s.lysenko@gmail.com</a>&gt; wrote:<br>
&gt; Felix,<br>
&gt;<br>
&gt; This seems to be very interestingly tied into your comments about polymorphism in &#39;throws&#39; type annotations. Would you not feel that allowing enums to be built on top of other enums would promote the kind of egregious proliferation of exception polymorphism that discourages so many from following Java&#39;s checked exception model?<br>
&gt;<br>
&gt; On Fri, Dec 18, 2015 at 11:29 AM Félix Cloutier &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br>
&gt; Hi all,<br>
&gt;<br>
&gt; Swift currently has more or less three conceptual types of enums: discriminated unions, lists of unique tokens, and lists of value of a raw type.<br>
&gt;<br>
&gt; &gt; // Discriminated unions<br>
&gt; &gt; enum Foo {<br>
&gt; &gt;       case Bar(Int)<br>
&gt; &gt;       case Baz(String)<br>
&gt; &gt; }<br>
&gt; &gt;<br>
&gt; &gt; // Lists of unique tokens (mixable with discriminated unions)<br>
&gt; &gt; enum Foo {<br>
&gt; &gt;       case Frob<br>
&gt; &gt;       case Nicate<br>
&gt; &gt; }<br>
&gt; &gt;<br>
&gt; &gt; // Lists of raw values<br>
&gt; &gt; enum Foo: String {<br>
&gt; &gt;       case Bar = &quot;Bar&quot;<br>
&gt; &gt;       case Baz = &quot;Baz&quot;<br>
&gt; &gt; }<br>
&gt;<br>
&gt; I think that the last case could be made more interesting if you could use more types as underlying types. For instance, it could probably be extended to support another enum as the backing type. One possible use case would be to have a big fat enum for all the possible errors that your program/library can throw, but refine that list into a shorter enum for functions that don&#39;t need it all.<br>
&gt;<br>
&gt; &gt; enum MyLibError: ErrorType {<br>
&gt; &gt;       case FileNotFound<br>
&gt; &gt;       case UnexpectedEOF<br>
&gt; &gt;       case PermissionDenied<br>
&gt; &gt;       // ... 300 cases later<br>
&gt; &gt;       case FluxCapacitorFailure<br>
&gt; &gt;       case SplineReticulationError<br>
&gt; &gt; }<br>
&gt; &gt;<br>
&gt; &gt; enum FileSystemError: MyLibError {<br>
&gt; &gt;       case FileNotFound = .FileNotFound<br>
&gt; &gt;       case UnexpectedEOF = .UnexpectedEOF<br>
&gt; &gt;       case PermissionDenied = .PermissionDenied<br>
&gt; &gt; }<br>
&gt;<br>
&gt; This example could be made simpler if the `= .Foo` part was inferred from the name, but you get the idea.<br>
&gt;<br>
&gt; In this case, it would be helpful (but not required) that FileSystemError was convertible into a MyLibError, so that it could be transparently rethrown in a function that uses the larger enum. I personally don&#39;t see why enums with a specified underlying type can&#39;t be implicitly converted to it, but this is not currently the case and it probably deserves some discussion as well.<br>
&gt;<br>
&gt; Is there any interest in that?<br>
&gt;<br>
&gt; Félix<br>
&gt;<br>
&gt; _______________________________________________<br>
&gt; swift-evolution mailing list<br>
&gt; <a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br>
&gt; <a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
&gt;<br>
&gt;<br>
&gt; _______________________________________________<br>
&gt; swift-evolution mailing list<br>
&gt; <a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br>
&gt; <a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
&gt;<br>
&gt;<br>
&gt;  _______________________________________________<br>
&gt; swift-evolution mailing list<br>
&gt; <a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br>
&gt; <a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
<br>
</blockquote></div>