> Am 26.05.2016 um 15:40 schrieb Matthew Johnson <[email protected]>:
>
>
>
> Sent from my iPad
>
> On May 26, 2016, at 8:25 AM, Thorsten Seitz <[email protected]
> <mailto:[email protected]>> wrote:
>
>> Ceylon requires checks whether cases are disjoint, i.e. when one case
>> contains a superclass of another case then this will be a type error „cases
>> are not disjoint“.
>>
>> FWIW: Ceylon requires classes with enumerated subclasses to be abstract.
>
> Interesting, thanks for mentioning this. The abstract requirement is what
> makes disjointedness at least partly possible (what if a subclass has further
> descendants though?). But it still only works for a single level of
> inheritance:
>
> sealed abstract class A {}
> class B : A {}
> class C : A {}
> class D : B {}
> class E : B {}
>
> With a disjoint requirement I cannot ever match D and E because that would
> not be exhaustive and I am prohibited from matching them along side B which
> would be exhaustive but isn't disjoint.
Why?
switch a {
case C: …
case D: …
case E: …
}
is exhaustive because B has to be sealed as well (I would require this to be
declared explicitly).
Abstractness seems not to be necessary for that IMO.
Either you match against B *or* against all its subclasses.
Example in Ceylon:
abstract class Parent() of Child1 | Child2 {}
class Child1() extends Parent() {}
abstract class Child2() of Grandchild1 | Grandchild2 extends Parent() {}
class Grandchild1() extends Child2() {}
class Grandchild2() extends Child2() {}
void main() {
Parent foo = Child1();
switch (foo)
case (is Child1) {
print("Child1");
}
case (is Grandchild1) {
print("Grandchild1");
}
case (is Grandchild2) {
print("Grandchild2");
}
}
-Thorsten
>
> I don't think that solution is appropriate to Swift.
>
>>
>> -Thorsten
>>
>>
>>> Am 25.05.2016 um 19:49 schrieb Matthew Johnson via swift-evolution
>>> <[email protected] <mailto:[email protected]>>:
>>>
>>>
>>>
>>> Sent from my iPad
>>>
>>> On May 25, 2016, at 12:41 PM, Charlie Monroe <[email protected]
>>> <mailto:[email protected]>> wrote:
>>>
>>>>> Got it. You could also say it is safer because you can't have a
>>>>> supertype case "swallow" a subtype value accidentally. An "exact type"
>>>>> cast would prevent this possibility.
>>>>
>>>> This still can be an issue since you still need to do the switch in
>>>> init(instance:), but it's just one place within the entire module, so it
>>>> can be more easily managed...
>>>
>>> Yes, agree. That's why your enum is safer. I think we do need an exact
>>> type cast to prevent this problem. 'isExaclty' and 'asExactly' seem are a
>>> bit verbose but are very clear. I can't think of anything I like that is
>>> more concise.
>>>
>>>>
>>>>>
>>>>>>
>>>>>> enum AnimalSubclasses {
>>>>>>
>>>>>> case Dog
>>>>>> case Cat
>>>>>>
>>>>>> init(instance: Animal) {
>>>>>> switch instance {
>>>>>> case is Dog: self = .Dog
>>>>>> case is Cat: self = .Cat
>>>>>> default: fatalError("Unhandled instance \(instance)!")
>>>>>> }
>>>>>>
>>>>>> }
>>>>>>
>>>>>>> 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
>>>>>>>>> <[email protected] <mailto:[email protected]>> 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:[email protected]>
>>>>>>>>> Sent: 24/05/2016 11:01 PM
>>>>>>>>> To: Austin Zheng <mailto:[email protected]>
>>>>>>>>> Cc: Leonardo Pessoa <mailto:[email protected]>; swift-evolution
>>>>>>>>> <mailto:[email protected]>
>>>>>>>>> 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
>>>>>>>>> <[email protected] <mailto:[email protected]>> 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 <[email protected]
>>>>>>>>>> <mailto:[email protected]>> 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
>>>>>>>>>> <[email protected] <mailto:[email protected]>> 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
>>>>>>>>>> > <[email protected] <mailto:[email protected]>>
>>>>>>>>>> > 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
>>>>>>>>>> >> [email protected] <mailto:[email protected]>
>>>>>>>>>> >> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>>>>>>> >> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>>>>>>> >
>>>>>>>>>> >
>>>>>>>>>> >
>>>>>>>>>> > _______________________________________________
>>>>>>>>>> > swift-evolution mailing list
>>>>>>>>>> > [email protected] <mailto:[email protected]>
>>>>>>>>>> > https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>>>>>>> > <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>>>>>>> >
>>>>>>>>>>
>>>>>>>>>> _______________________________________________
>>>>>>>>>> swift-evolution mailing list
>>>>>>>>>> [email protected] <mailto:[email protected]>
>>>>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>>>>>> _______________________________________________
>>>>>>>>> swift-evolution mailing list
>>>>>>>>> [email protected] <mailto:[email protected]>
>>>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>>>>>
>>>>>>>> _______________________________________________
>>>>>>>> swift-evolution mailing list
>>>>>>>> [email protected] <mailto:[email protected]>
>>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>
>>> _______________________________________________
>>> swift-evolution mailing list
>>> [email protected] <mailto:[email protected]>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution