[swift-evolution] Draft Proposal: Declare variables in 'case' labels with multiple patterns
Erica Sadun
erica at ericasadun.com
Sat Jan 23 19:09:40 CST 2016
+1 too
-- E
> On Jan 23, 2016, at 6:08 PM, Jed Lewison via swift-evolution <swift-evolution at swift.org> wrote:
>
> Also +1. I've run into this a couple of times in the past week and the proposal would allow shorter and easier to read code.
>
> Sent from my iPhone
>
> On Jan 23, 2016, at 10:09 AM, Joe Groff via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>
>> This would be great. Other pattern matching languages with ML heritage can do this, the only reason Swift couldn't was time.
>>
>> -Joe
>>
>>> On Jan 22, 2016, at 7:39 PM, Andrew Bennett via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>>
>>> Hi,
>>>
>>> I'd like to discuss declaring variables in case labels with multiple patterns. I've written a draft proposal, but I'd like to discuss it first before formally proposing anything.
>>>
>>> https://github.com/therealbnut/swift-evolution/blob/a137202e41588b71d3c0511cff85f82ec5f65629/proposals/0023-declare-variables-in-case-labels-with-multiple-patterns.md <https://github.com/therealbnut/swift-evolution/blob/a137202e41588b71d3c0511cff85f82ec5f65629/proposals/0023-declare-variables-in-case-labels-with-multiple-patterns.md>
>>>
>>> In short:
>>>
>>> switch value {
>>> case let .Case1(x, 2), .Case2(2, x):
>>> print(x)
>>> }
>>>
>>> The original proposal is here, it may need to adapt after discussion, so I'll try to keep the proposal at that link up-to-date.
>>>
>>> Thanks,
>>> Andrew
>>>
>>> Declare variables in 'case' labels with multiple patterns
>>>
>>> Proposal: SE-0022 <https://github.com/therealbnut/swift-evolution/blob/master/proposals/0023-declare-variables-in-case-labels-with-multiple-patterns.md>
>>> Author(s): Andrew Bennett <https://github.com/therealbnut>
>>> Status: In Discussion
>>> Review manager: Not In Review
>>> Introduction
>>>
>>> In Swift 2, it is possible to match multiple patterns in cases. However cases cannot contain multiple patterns if the case declares variables.
>>>
>>> The following code currently produces an error:
>>>
>>> enum MyEnum {
>>> case Case1(Int,Float)
>>> case Case2(Float,Int)
>>> }
>>> switch value {
>>> case let .Case1(x, 2), .Case2(2, x):
>>> print(x)
>>> case .Case1, .Case2:
>>> break
>>> }
>>> The error is:
>>>
>>> `case` labels with multiple patterns cannot declare variables.
>>> This proposal aims to remove this error when each pattern declares the same variables with the same types.
>>>
>>> Motivation
>>>
>>> This change reduces repeditive code, and therefore reduces mistakes. It's consistent with multi-pattern matching when variables aren't defined.
>>>
>>> Proposed solution
>>>
>>> Allow case labels with multiple patterns to declare patterns by matching variable names in each pattern.
>>>
>>> Using the following enum:
>>>
>>> enum MyEnum {
>>> case Case1(Int,Float)
>>> case Case2(Float,Int)
>>> }
>>> These cases should be possible:
>>>
>>> case let .Case1(x, _), .Case2(_, x):
>>> case let .Case1(y, x), .Case2(x, y):
>>> case let .Case1(x), .Case2(x):
>>> case .Case1(let x, _), .Case2(_, let x):
>>> Detailed design
>>>
>>> Allow case labels with multiple patterns if the case labels match the following constraints:
>>>
>>> All patterns declare exactly the same variables.
>>> The same variable has the same type in each pattern.
>>> Therefore each pattern is able to produce the same variables for the case label.
>>>
>>> Impact on existing code
>>>
>>> This should have no impact on existing code, although it should offer many opportunities for existing code to be simplified.
>>>
>>> Alternatives considered
>>>
>>> Using a closure or inline function
>>>
>>> Code repitition can be reduced with one pattern per 'case' and handling the result with an inline function.
>>>
>>> func handleCases(value: MyEnum, apply: Int -> Int) -> Int {
>>> func handleX(x: Int) -> Int {
>>> return apply(x) + 1
>>> }
>>> let out: Int
>>> switch value {
>>> case .Case1(let x, 2):
>>> out = handleX(x)
>>> case .Case2(2, let x):
>>> out = handleX(x)
>>> case .Case1, .Case2:
>>> out = -1
>>> }
>>> return out
>>> }
>>> This syntax is much more verbose, makes control flow more confusing, and has the limitations of the what the inline function may capture.
>>>
>>> In the above example apply cannot be @noescape because handleX captures it.
>>>
>>> Also in the above example if out is captured and assigned by handleX then it must be var, not let. This can produce shorter syntax, but is not as safe; out may accidentally be assigned more than once, additionally out also needs to initialized (which may not be possible or desirable).
>>>
>>> Extending the fallthrough syntax
>>>
>>> A similar reduction in code repetition can be achieved if fallthrough allowed variables to be mapped onto the next case, for example:
>>>
>>> switch test {
>>> case .Case1(let x, 2):
>>> fallthrough .Case2(_, x)
>>> case .Case2(3, .let x):
>>> print("x: \(x)")
>>> }
>>> This is not as intuitive, is a hack, and fallthrough should probably be discouraged. It is much more flexible, a programmer could adjust the value of x before fallthrough. Flexibility increases the chances of programmer error, perhaps not as much as code-repitition though.
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160123/5c08dd0f/attachment.html>
More information about the swift-evolution
mailing list