> On May 25, 2016, at 12:38 AM, Charlie Monroe via swift-evolution > <swift-evolution@swift.org> wrote: > > There are legit cases where you want to be able to subclass the class within > a module (framework), but you don't want others to subclass it out of the > framework in order to provide some integrity. This is usually done nowadays > (on many places within Apple's frameworks) by an assertion in init. > > It is very similar to declaring public internal(set) var - but with a class > and subclassing instead of modifying the contents of a var. > > And without it, you can't do this efficiently - the default case is dangerous > if you have a variable that returns non-nil value depending on the class - > the default case usually has fatalError() inside - forgetting to add the > clause for a new class won't be discovered until runtime.
+1 about not being notified of missing cases if you add a new conforming type or subclass. This is a big part of the reason for doing tis. > > I personally bypass this currently by having an enum of classes defined with > an initializer init(instance:) and then switch by the enum, which is safer > than switch by type - but it's extra work. Do you mean safer because you con’t forget to add new cases? Or just safer in general? One thing I have considered that might also be worth introducing is an exact match cast. This would prevent the possibility of putting a superclass case first and having it “steal” subclasses which were intended to be covered by a case later in the switch. If we introduce exact match you would be able to write a switch that must always cover every concrete type, including all subclasses. > > Charlie > > >> On May 25, 2016, at 4:41 AM, Leonardo Pessoa via swift-evolution >> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >> >> Limiting the amount of subclasses is not really a good idea as you would >> need to introduce another mechanism in the language while the proposed >> feature requires much less. And you're thinking only about the restrictive >> set (internal and private) and forgetting the more open end (public). Why is >> it so bad for this proposal to support requiring the default case? If its >> possible for the compiler to discover you covered all possible cases it >> would be fine not having default but IMHO in most cases it will find out >> there are more not explicitly covered. >> From: David Sweeris <mailto:daveswee...@mac.com> >> Sent: 24/05/2016 11:01 PM >> To: Austin Zheng <mailto:austinzh...@gmail.com> >> Cc: Leonardo Pessoa <mailto:m...@lmpessoa.com>; swift-evolution >> <mailto:swift-evolution@swift.org> >> Subject: Re: [swift-evolution] [Pitch] Exhaustive pattern matching >> forprotocols and classes >> >> Or if there was a way to declare that a class/protocol can only have a >> defined set of subclasses/conforming types. >> >> Sent from my iPhone >> >> On May 24, 2016, at 15:35, Austin Zheng via swift-evolution >> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >> >>> If you pattern match on a type that is declared internal or private, it is >>> impossible for the compiler to not have an exhaustive list of subclasses >>> that it can check against. >>> >>> Austin >>> >>> On Tue, May 24, 2016 at 1:29 PM, Leonardo Pessoa <m...@lmpessoa.com >>> <mailto:m...@lmpessoa.com>> wrote: >>> I like this but I think it would be a lot hard to ensure you have all >>> subclasses covered. Think of frameworks that could provide many >>> unsealed classes. You could also have an object that would have to >>> handle a large subtree (NSObject?) and the order in which the cases >>> are evaluated would matter just as in exception handling in languages >>> such as Java (or require some evaluation from the compiler to raise >>> warnings). I'm +1 for this but these should be open-ended like strings >>> and require the default case. >>> >>> On 24 May 2016 at 17:08, Austin Zheng via swift-evolution >>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >>> > I have been hoping for the exhaustive pattern matching feature for a while >>> > now, and would love to see a proposal. >>> > >>> > Austin >>> > >>> > On Tue, May 24, 2016 at 1:01 PM, Matthew Johnson via swift-evolution >>> > <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >>> >> >>> >> Swift currently requires a default pattern matching clause when you >>> >> switch >>> >> on an existential or a non-final class even if the protocol or class is >>> >> non-public and all cases are covered. It would be really nice if the >>> >> default clause were not necessary in this case. The compiler has the >>> >> necessary information to prove exhaustiveness. >>> >> >>> >> Related to this is the idea of introducing something like a `sealed` >>> >> modifier that could be applied to public protocols and classes. The >>> >> protocol or class would be visible when the module is imported, but >>> >> conformances or subclasses outside the declaring module would be >>> >> prohibited. >>> >> Internal and private protocols and classes would implicitly be sealed >>> >> since >>> >> they are not visible outside the module. Any protocols that inherit >>> >> from a >>> >> sealed protocol or classes that inherit from a sealed class would also be >>> >> implicitly sealed (if we didn’t do this the sealing of the superprotocol >>> >> / >>> >> superclass could be violated by conforming to or inheriting from a >>> >> subprotocol / subclass). >>> >> >>> >> Here are examples that I would like to see be valid: >>> >> >>> >> protocol P {} >>> >> // alternatively public sealed protocol P {} >>> >> struct P1: P {} >>> >> struct P2: P {} >>> >> >>> >> func p(p: P) -> Int { >>> >> switch p { >>> >> case is P1: return 1 // alternatively an `as` cast >>> >> case is P2: return 2 // alternatively an `as` cast >>> >> } >>> >> } >>> >> >>> >> class C {} >>> >> // alternatively public sealed class C {} >>> >> class C1: C {} >>> >> class C2: C {} >>> >> >>> >> func c(c: C) -> Int { >>> >> switch c { >>> >> case is C1: return 1 // alternatively an `as` cast >>> >> case is C2: return 2 // alternatively an `as` cast >>> >> case is C: return 0 // alternatively an `as` cast >>> >> } >>> >> } >>> >> >>> >> I am wondering if this is something the community is interested in. If >>> >> so, I am wondering if this is something that might be possible in the >>> >> Swift >>> >> 3 timeframe (maybe just for private and internal protocols and classes) >>> >> or >>> >> if it should wait for Swift 4 (this is likely the case). >>> >> >>> >> -Matthew >>> >> _______________________________________________ >>> >> swift-evolution mailing list >>> >> swift-evolution@swift.org <mailto:swift-evolution@swift.org> >>> >> https://lists.swift.org/mailman/listinfo/swift-evolution >>> >> <https://lists.swift.org/mailman/listinfo/swift-evolution> >>> > >>> > >>> > >>> > _______________________________________________ >>> > swift-evolution mailing list >>> > swift-evolution@swift.org <mailto:swift-evolution@swift.org> >>> > https://lists.swift.org/mailman/listinfo/swift-evolution >>> > <https://lists.swift.org/mailman/listinfo/swift-evolution> >>> > >>> >>> _______________________________________________ >>> swift-evolution mailing list >>> swift-evolution@swift.org <mailto:swift-evolution@swift.org> >>> https://lists.swift.org/mailman/listinfo/swift-evolution >>> <https://lists.swift.org/mailman/listinfo/swift-evolution> >> _______________________________________________ >> swift-evolution mailing list >> swift-evolution@swift.org <mailto: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