There has been a little discussion on this before, and I think there's a need for something along these lines - I've written code where I've used 'guard' to ensure that an Int was within a certain range, and then performed a switch on the Int, requiring an ugly-looking 'default: fatalError()' at the end to dismiss the warning.
But exhaustive switches are also useful. There was an elegant suggestion that we apply '?' and '!' to the switch keyword. Basically: - 'switch <expression>' is exhaustive across values and enum states and the compiler will warn you if you omit an enum state or default case. - 'switch? <expression>' is not exhaustive but the compiler should still check the flow (to ensure all paths return values, that kind of thing). - 'switch! <expression>' is not exhaustive but it assumes one of the cases will match, and crashes otherwise. Basically, switch wouldn't change, but appending the '?' is equivalent to typing 'default: break' as your final case, and appending '!' is equivalent to typing 'default: fatalError()' as your final case. The meanings are roughly analogous to their meanings for Optionals, so hopefully there wouldn't be much confusion. On Mon, Oct 3, 2016 at 11:55 AM, Adrian Zubarev via swift-evolution < swift-evolution@swift.org> wrote: > This is clearly not a huge issue to solve, but a pitch is a pitch. > > From Swift book we know this: > > *Switch Statements Must Be Exhaustive* > > In Swift, every possible value of the control expression’s type must match > the value of at least one pattern of a case. When this simply isn’t > feasible (for instance, when the control expression’s type is Int), you can > include a default case to satisfy the requirement. > > Even for enum values an optional default would mean that you don’t care > about the other cases in your current switch, which basically again would > be another useless nop. > > enum A { > case a, b, c > } > > var value = A.a > > switch value { > > case .a: > value = A.b > > default: > () // I don't care > } > > // Do something else > > switch value { > > case .b: > value = A.c > > default: > () // I don't care > } > > Sure the error message is there to notify you that you might forget to > handle some case, but how we handle that specific case is still up to us. > > I’d really like to know what could be dangerous here when default would > be optional. > > I can’t tell if this would have some impact on the ABI or not. I’d say > it’s additive because it doesn’t break any existing code but removes an > existing restriction. > ------------------------------ > > The next thought might be an overkill (or maybe not): > > How about making default optional everywhere + introducing a new > attribute that allows the optional default on that particular enum, but > by default every current existing enum should be handled exhaustively. > > Bikeshedding: > > enum A { > case a, b, c > } > > var value = A.a > > switch value { > > case .a: > value = A.b > > } // Error: switch must be exhaustive, consider adding a default clause > > // VS: > > @discardableCase enum B { > case d, e, f > } > > let anotherValue = B.d > > switch anotherValue { > > case .d: > // Do something > > case .e: > // Do something else > > } // Just fine; We don't care here about `.f` > > > > -- > Adrian Zubarev > Sent with Airmail > > Am 3. Oktober 2016 um 12:28:58, Rien (r...@balancingrock.nl) schrieb: > > On non-enum values, yes I could support this. However I do not see this as > a big enough issue. > On enum values? no way…. > > Btw this would get rid of: > > let bytesSend = send(…) // returns an Int > > switch bytesSend { > case Int.min ... -1: {…} > case 0: {…} > case 1 ... Int.max: {…} > default: break // <<<<<< Imposible > } > > > > > > On 03 Oct 2016, at 12:14, Adrian Zubarev via swift-evolution < > swift-evolution@swift.org> wrote: > > > > I know that there is this note in Commonly Rejected Changes: > > > > Remove support for default: in switch and just use case _:: default is > widely used, case _ is too magical, and default is widely precedented in > many C family languages. > > I really like to use the switch instead of if case for pattern matching, > just because it’s neat block design. I do not want to remove default from > switches because it’s a must have and powerful feature. > > > > I’d like to know why switches must be exhaustive. > > > > switch someValue { > > > > case …: > > // Do something > > > > case …: > > // Do something else > > > > default: > > () // useless nop; do nothing when no pattern matched > > } > > > > // VS: > > > > if case … { > > > > } else if case … { > > > > } else if case … { > > > > } // No need for `else` > > > > Can’t we make default optional, or at least on non-enum values? > > > > > > > > > > -- > > Adrian Zubarev > > Sent with Airmail > > > > _______________________________________________ > > 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