Felix, I cannot speak for anyone but myself, but my idea was that the "included" cases would be treated as a member--whether first or second class, still a member--of the enum including them. I wholeheartedly agree that the example you wrote up would be undesirable.
On Sat, Dec 19, 2015, 4:36 PM Félix Cloutier <felix...@yahoo.ca> wrote: > I'm biased as the pitcher, but I find that an "inheritance" model would be > more straightforward than an inclusive model. > > If I understand you correctly, with this model: > > enum NetworkException { > case NoInternetError, SecurityError > } > > enum ChangePictureError { > case NetworkException(NetworkException) > case ParseException(ParseException) > case PictureTooLarge > } > > > you're saying that we should be able to write: > > let x: ChangePictureError = NetworkException.NoInternetError > > > The implicit conversion from NetworkException to ChangePictureError > reminds me of C++ implicit constructors, which are generally frowned upon, > so I'm not sure that this is the best way forward. > > On the other hand, going back to my original example: > > enum MyLibError: ErrorType { > case FileNotFound > case UnexpectedEOF > case PermissionDenied > // ... 300 cases later > case FluxCapacitorFailure > case SplineReticulationError > } > > enum FileSystemError: MyLibError { > case FileNotFound = .FileNotFound > case UnexpectedEOF = .UnexpectedEOF > case PermissionDenied = .PermissionDenied > } > > > I can easily rationalize that FileSystemError is implicitly convertible to > MyLibError because of the "inheritance" relationship. > > Félix > > > Le 19 déc. 2015 à 14:28:44, Matthew Johnson <matt...@anandabits.com> a > écrit : > > > On Dec 18, 2015, at 11:34 AM, Dennis Lysenko via swift-evolution < > swift-evolution@swift.org> wrote: > > 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' response to it. It is a very > interesting idea though. > > I'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? > > e.g., you have: > enum NetworkException { > case NoInternetError, SecurityError > } > > enum ParseException { > case FailedResponse(statusCode: Int) > case EmptyResponse > case MissingField(fieldName: String) > } > > 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 "please check your > connection" message for NoInternetError, a "Please log in" error for > FailedResponse with statusCode=401, or a "server error" message for any of > the rest. > > 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. > > Here are some quick code samples off the top of my head for how we might > go about this (let's say the API operation is "change profile picture": > > enum ChangePictureError { > include NetworkException > include ParseException > case PictureTooLarge > } > > > By including all of the cases you make it possible for ChangePictureError > to be a supertype of NetworkException and ParseException. This is a pretty > interesting idea. It might be worth exploring. > > One thing that would need to be considered is that ideally if the actual > values was a NetworkException case you would want to be able to call any > methods exposed by Network Exception. A good way to accomplish that might > be to add implicit conversion as well as syntactic sugar for nested enums. > So if we have this: > > enum ChangePictureError { > case NetworkException(NetworkException) > case ParseException(ParseException) > case PictureTooLarge > } > > I can do this: > > var error: ChangePictureError // set somewhere, can be set with a > NetworkException or a PictureTooLarge > switch error { > case .NoNetworkError: // equivaluent to case > .NetworkException(.NoNetworkError) > case .NoInternetError: // equivaluent to case > .NetworkException(. NoInternetError) > case .FailedResponse(let statusCode): // equivaluent to case > .ParseException(.FailedResponse(let statusCode)) > case .EmptyResponse: // equivaluent to case > .ParseException(.EmptyResponse) > case .MissingField(let fieldName): // equivaluent to case > .ParseException(. MissingField(let fieldName)) > case .PictureTooLarge: > } > > The syntactic sugar would only work for case names where there is no > overlap. Case names that overlap would need to be explicitly > disambiguated. The syntactic sugar and implicit conversions could allow > for either single-level nesting or arbitrary nesting depth. An example of > arbitrary depth might be ParseException also containing a ValidationError > case: > > enum ValidationError { > case OutOfRange > case InvalidType > } > > enum ParseException { > case ValidationError(ValidationError) > case FailedResponse(statusCode: Int) > case EmptyResponse > case MissingField(fieldName: String) > } > > Mostly just thinking out loud here and exploring the idea. What do others > think of this? > > > or > > enum ChangePictureError { > compose NetworkException.NoInternetError > compose ParseException.EmptyResponse > compose ParseException.FailedResponse(statusCode: Int) > case PictureTooLarge > } > > Not a proposal by any stretch of the imagination, just a potential > direction inspired by your idea, Felix. > > > On Fri, Dec 18, 2015 at 12:21 PM Dennis Lysenko < > dennis.s.lyse...@gmail.com> wrote: > >> Felix, >> >> This seems to be very interestingly tied into your comments about >> polymorphism in 'throws' 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's checked exception model? >> >> On Fri, Dec 18, 2015 at 11:29 AM Félix Cloutier < >> swift-evolution@swift.org> wrote: >> >>> Hi all, >>> >>> 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. >>> >>> > // Discriminated unions >>> > enum Foo { >>> > case Bar(Int) >>> > case Baz(String) >>> > } >>> > >>> > // Lists of unique tokens (mixable with discriminated unions) >>> > enum Foo { >>> > case Frob >>> > case Nicate >>> > } >>> > >>> > // Lists of raw values >>> > enum Foo: String { >>> > case Bar = "Bar" >>> > case Baz = "Baz" >>> > } >>> >>> 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't need it all. >>> >>> > enum MyLibError: ErrorType { >>> > case FileNotFound >>> > case UnexpectedEOF >>> > case PermissionDenied >>> > // ... 300 cases later >>> > case FluxCapacitorFailure >>> > case SplineReticulationError >>> > } >>> > >>> > enum FileSystemError: MyLibError { >>> > case FileNotFound = .FileNotFound >>> > case UnexpectedEOF = .UnexpectedEOF >>> > case PermissionDenied = .PermissionDenied >>> > } >>> >>> This example could be made simpler if the `= .Foo` part was inferred >>> from the name, but you get the idea. >>> >>> 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't see why enums with a specified underlying type can't be >>> implicitly converted to it, but this is not currently the case and it >>> probably deserves some discussion as well. >>> >>> Is there any interest in that? >>> >>> Félix >>> >>> _______________________________________________ >>> swift-evolution mailing list >>> swift-evolution@swift.org >>> https://lists.swift.org/mailman/listinfo/swift-evolution >>> >> _______________________________________________ > swift-evolution mailing list > swift-evolution@swift.org > https://lists.swift.org/mailman/listinfo/swift-evolution > > >
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution