> Le 18 nov. 2017 à 23:47, Xiaodi Wu <xiaodi...@gmail.com> a écrit :
> 
>> On Sat, Nov 18, 2017 at 16:25 Benjamin G <benjamin.garrig...@gmail.com> 
>> wrote:
>> I think because it's not immediately obvious with multiple if statement, 
>> that they all try to compare the same expression to different patterns.
>> 
>> match exp {
>> case 1
>> case 2
>> }
>> vs
>> if case 1 = exp
>> if case 2 = anotherexp 
> 
> And this is a problem that requires a new syntax because...?

i don't think the reason is that different from creating "switch" : you can 
very well use "ifs" instead, it's just more convenient . It may provide 
exhaustive check in the case of optionset one day. But we can live without it ( 
much like we lived without switch before).

Actually i think there's a nice symetry betwen enum & switch on one side and 
optionset & match on the other hand. It's interesting but i don't know if it's 
useful in practice TBH.


> 
> Consider that “exp” can be mutated in case 1; now reflect whether the 
> proposed syntax facilitates or hinders correct code.
> 
> 
>>> On Sat, Nov 18, 2017 at 10:43 PM, Xiaodi Wu via swift-evolution 
>>> <swift-evolution@swift.org> wrote:
>>>> On Sat, Nov 18, 2017 at 3:12 PM, Peter Kamb <peterk...@gmail.com> wrote:
>>> 
>>>> A high bar for new syntax is fair and expected, and by posting I was 
>>>> hoping to maybe find an alternative in the comments here.
>>>> 
>>>> But AFAIK there's currently no ability in Swift to:
>>>> 
>>>> "Evaluate a *single* control expression against all of these patterns, and 
>>>> execute any and all cases that match"
>>>> 
>>>> Multiple `if-case` statements, each re-stating the control expression, are 
>>>> ok.
>>>> 
>>>> But that's definitely not as clear or concise as a switch-like construct 
>>>> with the single control expression at the top. Or perhaps some other 
>>>> alternative such as the mentioned `continue` or somehow enumerating a set 
>>>> of cases.
>>> 
>>> You're simply restating your proposed new syntax as the thing that's 
>>> missing. But what is the use case that motivates this construct? In what 
>>> way are multiple if-case statements "not as clear"?
>>> 
>>>>> On Sat, Nov 18, 2017 at 11:18 AM, Xiaodi Wu <xiaodi...@gmail.com> wrote:
>>>>> Robert is quite right--I'm not sure what we're designing for here. 
>>>>> There's a very high bar for introducing new syntax and a distaste for the 
>>>>> existing syntax is not a motivating use case.
>>>>> 
>>>>> 
>>>>>> On Sat, Nov 18, 2017 at 12:53 PM, Kevin Nattinger via swift-evolution 
>>>>>> <swift-evolution@swift.org> wrote:
>>>>>> There have been earlier suggestions for an alternative to `fallthrough` 
>>>>>> that would continue matching cases; I think that is much more likely to 
>>>>>> get support than a whole new construct with only a subtle difference 
>>>>>> from an existing one—would that be an acceptable alternative to you?
>>>>>> 
>>>>>> > On Nov 17, 2017, at 12:06 PM, Peter Kamb via swift-evolution 
>>>>>> > <swift-evolution@swift.org> wrote:
>>>>>> >
>>>>>> > ## Title
>>>>>> >
>>>>>> > Add `match` statement as `switch`-like syntax alternative to `if case` 
>>>>>> > pattern matching
>>>>>> >
>>>>>> > ## Summary:
>>>>>> >
>>>>>> > The syntax of the `switch` statement is familiar, succinct, elegant, 
>>>>>> > and understandable. Swift pattern-matching tutorials use `switch` 
>>>>>> > statements almost exclusively, with small sections at the end for 
>>>>>> > alternatives such as `if case`.
>>>>>> >
>>>>>> > However, the `switch` statement has several unique behaviors unrelated 
>>>>>> > to pattern matching. Namely:
>>>>>> >
>>>>>> >  - Only the *first* matching case is executed. Subsequent matching 
>>>>>> > cases are not executed.
>>>>>> >  - `default:` case is required, even for expressions where a default 
>>>>>> > case does not make sense.
>>>>>> >
>>>>>> > These behaviors prevent `switch` from being used as a generic 
>>>>>> > match-patterns-against-a-single-expression statement.
>>>>>> >
>>>>>> > Swift should contain an equally-good pattern-matching statement that 
>>>>>> > does not limit itself single-branch switching.
>>>>>> >
>>>>>> > ## Pitch:
>>>>>> >
>>>>>> > Add a `match` statement with the same elegant syntax as the `switch` 
>>>>>> > statement, but without any of the "branch switching" baggage.
>>>>>> >
>>>>>> > ```
>>>>>> > match someValue {
>>>>>> > case patternOne:
>>>>>> >     always executed if pattern matches
>>>>>> > case patternTwo:
>>>>>> >     always executed if pattern matches
>>>>>> > }
>>>>>> > ```
>>>>>> >
>>>>>> > The match statement would allow a single value to be filtered through 
>>>>>> > *multiple* cases of pattern-matching evaluation.
>>>>>> >
>>>>>> > ## Example:
>>>>>> >
>>>>>> > ```
>>>>>> > struct TextFlags: OptionSet {
>>>>>> >     let rawValue: Int
>>>>>> >     static let italics = TextFlags(rawValue: 1 << 1)
>>>>>> >     static let bold    = TextFlags(rawValue: 1 << 2)
>>>>>> > }
>>>>>> >
>>>>>> > let textFlags: TextFlags = [.italics, .bold]
>>>>>> >
>>>>>> >
>>>>>> >
>>>>>> > // SWITCH STATEMENT
>>>>>> > switch textFlags {
>>>>>> > case let x where x.contains(.italics):
>>>>>> >     print("italics")
>>>>>> > case let x where x.contains(.bold):
>>>>>> >     print("bold")
>>>>>> > default:
>>>>>> >     print("forced to include a default case")
>>>>>> > }
>>>>>> > // prints "italics"
>>>>>> > // Does NOT print "bold", despite .bold being set.
>>>>>> >
>>>>>> >
>>>>>> >
>>>>>> > // MATCH STATEMENT
>>>>>> > match textFlags {
>>>>>> > case let x where x.contains(.italics):
>>>>>> >     print("italics")
>>>>>> > case let x where x.contains(.bold):
>>>>>> >     print("bold")
>>>>>> > }
>>>>>> > // prints "italics"
>>>>>> > // prints "bold"
>>>>>> > ```
>>>>>> >
>>>>>> > ## Enum vs. OptionSet
>>>>>> >
>>>>>> > The basic difference between `switch` and `match` is the same 
>>>>>> > conceptual difference between `Emum` and an `OptionSet` bitmask.
>>>>>> >
>>>>>> > `switch` is essentially designed for enums: switching to a single 
>>>>>> > logical branch based on the single distinct case represented by the 
>>>>>> > enum.
>>>>>> >
>>>>>> > `match` would be designed for OptionSet bitmasks and similar 
>>>>>> > constructs. Executing behavior for *any and all* of the following 
>>>>>> > cases and patterns that match.
>>>>>> >
>>>>>> > The programmer would choose between `switch` or `match` based on the 
>>>>>> > goal of the pattern matching. For example, pattern matching a String. 
>>>>>> > `switch` would be appropriate for evaluating a String that represents 
>>>>>> > the rawValue of an enum. But `match` would be more appropriate for 
>>>>>> > evaluating a single input String against multiple 
>>>>>> > unrelated-to-each-other regexes.
>>>>>> >
>>>>>> > ## Existing Alternatives
>>>>>> >
>>>>>> > `switch` cannot be used to match multiple cases. There are several 
>>>>>> > ways "test a value against multiple patterns, executing behavior for 
>>>>>> > each pattern that matches", but none are as elegant and understandable 
>>>>>> > as the switch statement syntax.
>>>>>> >
>>>>>> > Example using a string of independent `if case` statements:
>>>>>> >
>>>>>> > ```
>>>>>> > if case let x = textFlags, x.contains(.italics) {
>>>>>> >     print("italics")
>>>>>> > }
>>>>>> >
>>>>>> > if case let x = textFlags, x.contains(.bold) {
>>>>>> >     print("bold")
>>>>>> > }
>>>>>> > ```
>>>>>> >
>>>>>> > ## `match` statement benefits:
>>>>>> >
>>>>>> >  - Allow filtering a single object through *multiple* cases of pattern 
>>>>>> > matching, executing *all* cases that match.
>>>>>> >
>>>>>> >  - A syntax that exactly aligns with the familiar, succinct, elegant, 
>>>>>> > and understandable `switch` syntax.
>>>>>> >
>>>>>> > - The keyword "match" highlights that pattern matching will occur. 
>>>>>> > Would be even better than `switch` for initial introductions to 
>>>>>> > pattern-matching.
>>>>>> >
>>>>>> >  - No need to convert between the strangely slightly different syntax 
>>>>>> > of `switch` vs. `if case`, such as `case let x where 
>>>>>> > x.contains(.italics):` to `if case let x = textFlags, 
>>>>>> > x.contains(.italics) {`
>>>>>> >
>>>>>> >  - Bring the "Expression Pattern" to non-branch-switching contexts. 
>>>>>> > Currently: "An expression pattern represents the value of an 
>>>>>> > expression. Expression patterns appear only in switch statement case 
>>>>>> > labels."
>>>>>> >
>>>>>> >  - A single `match controlExpression` at the top rather than 
>>>>>> > `controlExpression` being repeated (and possibly changed) in every 
>>>>>> > single `if case` statement.
>>>>>> >
>>>>>> >  - Duplicated `controlExpression` is an opportunity for bugs such as 
>>>>>> > typos or changes to the expression being evaluated in a *single* `if 
>>>>>> > case` from the set, rather than all cases.
>>>>>> >
>>>>>> >  - Reduces to a pretty elegant single-case. This one-liner is an easy 
>>>>>> > "just delete whitespace" conversion from standard multi-line 
>>>>>> > switch/match syntax, whereas `if case` is not.
>>>>>> >
>>>>>> > ```
>>>>>> >  match value { case pattern:
>>>>>> >     print("matched")
>>>>>> > }
>>>>>> > ```
>>>>>> >
>>>>>> >  - Eliminate the boilerplate `default: break` case line for 
>>>>>> > non-exhaustible expressions. Pretty much any non-Enum type being 
>>>>>> > evaluated is non-exhaustible. (This is not the *main* goal of this 
>>>>>> > proposal.)
>>>>>> >
>>>>>> > ## Prototype
>>>>>> >
>>>>>> > A prototype `match` statement can be created in Swift by wrapping a 
>>>>>> > `switch` statement in a loop and constructing each case to match only 
>>>>>> > on a given iteration of the loop:
>>>>>> >
>>>>>> > ```
>>>>>> > match: for eachCase in 0...1 {
>>>>>> > switch (eachCase, textFlags) {
>>>>>> > case (0, let x) where x.contains(.italics):
>>>>>> >     print("italics")
>>>>>> > case (1, let x) where x.contains(.bold):
>>>>>> >     print("bold")
>>>>>> > default: break }
>>>>>> > }
>>>>>> >
>>>>>> > // prints "italics"
>>>>>> > // prints "bold"
>>>>>> > ```
>>>>>> >
>>>>>> > ## Notes / Discussion:
>>>>>> >
>>>>>> > - Other Languages - I've been unable to find a switch-syntax 
>>>>>> > non-"switching" pattern-match operator in any other language. If you 
>>>>>> > know of any, please post!
>>>>>> >
>>>>>> > - Should `match` allow a `default:` case? It would be easy enough to 
>>>>>> > add one that functioned like switch's default case: run if *no other* 
>>>>>> > cases were executed. But, conceptually, should a "match any of these 
>>>>>> > patterns" statement have an else/default clause? I think it should, 
>>>>>> > unless there are any strong opinions.
>>>>>> >
>>>>>> > - FizzBuzz using proposed Swift `match` statement:
>>>>>> >
>>>>>> > ```
>>>>>> > for i in 1...100 {
>>>>>> >     var output = ""
>>>>>> >     match 0 {
>>>>>> >     case (i % 3): output += "Fizz"
>>>>>> >     case (i % 3): output += "Buzz"
>>>>>> >     default:      output = String(i)
>>>>>> >     }
>>>>>> >
>>>>>> >     print(output)
>>>>>> > }
>>>>>> >
>>>>>> > // `15` prints "FizzBuzz"
>>>>>> > ```
>>>>>> > _______________________________________________
>>>>>> > 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
>>> 
>> 
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to