# \[Idea\] \[Pitch\] Add \`match\` statement as \`switch\`-like syntax alternative to \`if case\` pattern matching

**URL:** <https://forums.swift.org/t/idea-pitch-add-match-statement-as-switch-like-syntax-alternative-to-if-case-pattern-matching/7095>\
**Category:** Pitches\
**Created:** [November 17, 2017, 8:05pm UTC](https://forums.swift.org/t/idea-pitch-add-match-statement-as-switch-like-syntax-alternative-to-if-case-pattern-matching/7095 "2017-11-17T20:05:32Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![pkamb](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/pkamb/32/2500_2.png) [@pkamb](https://forums.swift.org/u/pkamb)\
**Post date:** [November 17, 2017, 8:05pm UTC](https://forums.swift.org/t/idea-pitch-add-match-statement-as-switch-like-syntax-alternative-to-if-case-pattern-matching/7095/1 "2017-11-17T20:05:32Z")

</div>

## 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.

```swift
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:

```swift
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:

```swift
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.

```swift
 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:

```swift
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:

```swift
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"

```

---

<div class="post-metadata">

**Author:** ![codafi](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/codafi/32/791_2.png) [@codafi](https://forums.swift.org/u/codafi)\
**Post date:** [November 18, 2017, 8:19am UTC](https://forums.swift.org/t/idea-pitch-add-match-statement-as-switch-like-syntax-alternative-to-if-case-pattern-matching/7095/2 "2017-11-18T08:19:05Z")

</div>

Having spent a lot of time with ‘switch’, I don’t understand any of the motivations or corresponding justifications for this idea. Comments inline:

~Robert Widmann

2017/11/17 15:06、Peter Kamb via swift-evolution \<swift-evolution@swift.org\>のメール:

> ## 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.

This is not unrelated to pattern matching, this is the expected behavior of every pattern matching algorithm. The intent is to compile a switch-case tree down to (conceptually) a (hopefully minimal) if-else tree. You may be thinking of the behavior of switch in C and C-likes which is most certainly not pattern matching and includes behavior Swift has explicitly chosen to avoid like implicit fallthroughs.

> - `default:` case is required, even for expressions where a default case does not make sense.

Expression patterns may look to be covered “at first glance”, but the analysis required to prove that is equivalent to solving the halting problem in the general case. Further, your proposed idea has absolutely nothing to do with this.

> 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.
> 
> ```swift
> 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:
> 
> ```swift
> 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:
> 
> ```swift
> 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.

Again, this is not pattern matching.

> - A syntax that exactly aligns with the familiar, succinct, elegant, and understandable `switch` syntax.

A syntax that duplicates the existing if-case construct which, I should note, takes the same number of lines and roughly the same number of columns to express as your match. Even less, considering you unwrap in the if-case to exaggerate the example but not in the match.

> - 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.
> 
> ```swift
> 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.)

This is not boilerplate!

> ## 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:
> 
> ```swift
> 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:
> 
> ```swift
> 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"
> 
> ```

for i in 1...100 {  
&nbsp;&nbsp;var output = “”  
&nbsp;&nbsp;output += (i % 3 == 0) ? “Fizz” : “”  
&nbsp;&nbsp;output += (i % 5 == 0) ? “Buzz” : “”  
&nbsp;&nbsp;print(output.isEmpty ? “\(i)” : output)  
}

If control flow should branch multiple times, why not write just write it that way!

> **···**
>
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![knatt](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/knatt/32/22335_2.png) [@knatt](https://forums.swift.org/u/knatt)\
**Post date:** [November 18, 2017, 6:53pm UTC](https://forums.swift.org/t/idea-pitch-add-match-statement-as-switch-like-syntax-alternative-to-if-case-pattern-matching/7095/3 "2017-11-18T18:53:12Z")

</div>

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.
> > 
> > ```swift
> > 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:
> > 
> > ```swift
> > 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:
> > 
> > ```swift
> > 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.
> > 
> > ```swift
> > 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:
> > 
> > ```swift
> > 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:
> > 
> > ```swift
> > 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](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![Tino](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tino/32/1073_2.png) [@Tino](https://forums.swift.org/u/Tino)\
**Post date:** [November 18, 2017, 11:40am UTC](https://forums.swift.org/t/idea-pitch-add-match-statement-as-switch-like-syntax-alternative-to-if-case-pattern-matching/7095/4 "2017-11-18T11:40:25Z")

</div>

I haven’t spend that much time on thinking about the implications, but at first sight, it sounds like a sensible idea — maybe even more useful than switch (whose behavior could be mimicked).  
But switch is established, and I don’t see a realistic chance to either replace it or add a construct that is quite similar.  
Afaics, it will already be hard to collect feedback, so it might be a good idea to delay the pitch until the move to Discourse is done.

---

<div class="post-metadata">

**Author:** ![pkamb](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/pkamb/32/2500_2.png) [@pkamb](https://forums.swift.org/u/pkamb)\
**Post date:** [November 18, 2017, 9:42am UTC](https://forums.swift.org/t/idea-pitch-add-match-statement-as-switch-like-syntax-alternative-to-if-case-pattern-matching/7095/5 "2017-11-18T09:42:10Z")

</div>

Thanks for the review.

Motivation is essentially to provide a low-friction way to write `if case /  
if case / if case` statements that are all matching on the same expression,  
much in the same way that `switch` offers a way to write `if / else if /  
else` statements against the same expression.

\> \> Only the \*first\* matching case is executed. Subsequent matching cases  
are not executed.  
\> This is not unrelated to pattern matching, this is the expected behavior  
of every pattern matching algorithm.

By that I meant that a string of `if case / if case / if case` statements,  
each individually matching against the same expression, would match and  
execute all 3 cases. A `switch` using the same 3 cases would execute only  
the first matching case. I took the "only first case" behavior to be a  
property of the \*switch\*, not of "pattern matching" in general? But perhaps  
I'm using the wrong terminology.

\> \> Allow filtering a single object through \*multiple\* cases of pattern  
matching, executing \*all\* cases that match.  
\> Again, this is not pattern matching.

A switch can have multiple cases that "would" match and execute, if you  
were to comment out the successful case above them. Why would a  
hypothetical statement that executed \*all\* matching cases, rather than just  
the first case, not be pattern matching? It wouldn't be a `switch`, for  
sure, but it seems like it would be just as much "pattern matching" as an  
`if-case`.

\> This is not boilerplate!

An `if case / if case` pair would not have the same concept of a shared  
`else/default` case used by a `switch` or `if/else`, which is why I said it  
would not be needed. `if-case` does not require an else/default. (Perhaps  
boilerplate was the wrong word, and I definitely didn't mean to suggest  
that switches should no longer require `default:`).

\> A syntax that duplicates the existing if-case construct

Right, it would duplicate `if-case` just as `switch` duplicates `if-else`.

Cheers, thanks.

Peter

> **···**
>
> On Sat, Nov 18, 2017 at 12:19 AM, Robert Widmann \<devteam.codafi@gmail.com\> wrote:
> 
> > Having spent a lot of time with ‘switch’, I don’t understand any of the  
> > motivations or corresponding justifications for this idea. Comments inline:
> > 
> > ~Robert Widmann
> > 
> > 2017/11/17 15:06、Peter Kamb via swift-evolution \<swift-evolution@swift.org  
> > \>のメール:
> > 
> > ## 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.
> > 
> > This is not unrelated to pattern matching, this is the expected behavior  
> > of every pattern matching algorithm. The intent is to compile a  
> > switch-case tree down to (conceptually) a (hopefully minimal) if-else  
> > tree. You may be thinking of the behavior of switch in C and C-likes which  
> > is most certainly not pattern matching and includes behavior Swift has  
> > explicitly chosen to avoid like implicit fallthroughs.
> > 
> > - `default:` case is required, even for expressions where a default case  
> > does not make sense.
> > 
> > Expression patterns may look to be covered “at first glance”, but the  
> > analysis required to prove that is equivalent to solving the halting  
> > problem in the general case. Further, your proposed idea has absolutely  
> > nothing to do with this.
> > 
> > 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.
> > 
> > ```swift
> > 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:
> > 
> > ```swift
> > 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:
> > 
> > ```swift
> > 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.
> > 
> > Again, this is not pattern matching.
> > 
> > - A syntax that exactly aligns with the familiar, succinct, elegant, and  
> > understandable `switch` syntax.
> > 
> > A syntax that duplicates the existing if-case construct which, I should  
> > note, takes the same number of lines and roughly the same number of columns  
> > to express as your match. Even less, considering you unwrap in the if-case  
> > to exaggerate the example but not in the match.
> > 
> > - 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.
> > 
> > ```swift
> > 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.)
> > 
> > This is not boilerplate!
> > 
> > ## 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:
> > 
> > ```swift
> > 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:
> > 
> > ```swift
> > 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"
> > 
> > ```
> > 
> > for i in 1...100 {  
> > &nbsp;&nbsp;var output = “”  
> > &nbsp;&nbsp;output += (i % 3 == 0) ? “Fizz” : “”  
> > &nbsp;&nbsp;output += (i % 5 == 0) ? “Buzz” : “”  
> > &nbsp;&nbsp;print(output.isEmpty ? “\(i)” : output)  
> > }
> > 
> > If control flow should branch multiple times, \*why not write just write  
> > it that way!\*
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [November 18, 2017, 7:18pm UTC](https://forums.swift.org/t/idea-pitch-add-match-statement-as-switch-like-syntax-alternative-to-if-case-pattern-matching/7095/6 "2017-11-18T19:18:06Z")

</div>

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](https://lists.swift.org/mailman/listinfo/swift-evolution)
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![codafi](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/codafi/32/791_2.png) [@codafi](https://forums.swift.org/u/codafi)\
**Post date:** [November 18, 2017, 6:48pm UTC](https://forums.swift.org/t/idea-pitch-add-match-statement-as-switch-like-syntax-alternative-to-if-case-pattern-matching/7095/7 "2017-11-18T18:48:31Z")

</div>

> Thanks for the review.
> 
> Motivation is essentially to provide a low-friction way to write `if case / if case / if case` statements that are all matching on the same expression, much in the same way that `switch` offers a way to write `if / else if / else` statements against the same expression.

That much I understand, but there’s no motivation as to why this kind of change needs to occur over a line of if-case statements. There isn’t anything in the pitch that demonstrates friction outside of a personal distaste for the syntax.

> \> \> Only the \*first\* matching case is executed. Subsequent matching cases are not executed.  
> \> This is not unrelated to pattern matching, this is the expected behavior of every pattern matching algorithm.
> 
> By that I meant that a string of `if case / if case / if case` statements, each individually matching against the same expression, would match and execute all 3 cases. A `switch` using the same 3 cases would execute only the first matching case. I took the "only first case" behavior to be a property of the \*switch\*, not of "pattern matching" in general? But perhaps I'm using the wrong terminology.
> 
> \> \> Allow filtering a single object through \*multiple\* cases of pattern matching, executing \*all\* cases that match.  
> \> Again, this is not pattern matching.
> 
> A switch can have multiple cases that "would" match and execute, if you were to comment out the successful case above them. Why would a hypothetical statement that executed \*all\* matching cases, rather than just the first case, not be pattern matching? It wouldn't be a `switch`, for sure, but it seems like it would be just as much "pattern matching" as an `if-case`.

It is not pattern matching because it violates minimality - and we have a warning today when you write switches of overlapping patterns. Consider the semantics of pattern matching in the context of a tree - but it just so happens the nodes of this tree are your patterns and the branches, actual branches where control flow splits along the case-matrix. The goal is not to execute a find-all, the goal is to execute a find - exactly like a regular expression.

> \> This is not boilerplate!
> 
> An `if case / if case` pair would not have the same concept of a shared `else/default` case used by a `switch` or `if/else`, which is why I said it would not be needed. `if-case` does not require an else/default. (Perhaps boilerplate was the wrong word, and I definitely didn't mean to suggest that switches should no longer require `default:`).

You misunderstand me. This is the same problem as the one I brought up before: You are subject to the halting problem in the general case. The catch-all clause isn’t just noise, it’s a fundamental necessity to guarantee sound semantics for this particular class of switch statements that, according to a fundamental barrier in computer science, cannot be checked for exhaustiveness.

On top of that, we cannot allow you to write an uncovered switch statement full of expression patterns because you would most-assuredly not handle all possible cases (suppose I extend your OptionSet with a new bit-pattern in a different module - your code will miscompile).

> **···**
>
> > On Nov 18, 2017, at 4:42 AM, Peter Kamb \<peterkamb@gmail.com\> wrote:
> 
> > On Sat, Nov 18, 2017 at 12:19 AM, Robert Widmann \<devteam.codafi@gmail.com \<mailto:devteam.codafi@gmail.com\>\> wrote:  
> > Having spent a lot of time with ‘switch’, I don’t understand any of the motivations or corresponding justifications for this idea. Comments inline:
> > 
> > ~Robert Widmann
> > 
> > 2017/11/17 15:06、Peter Kamb via swift-evolution \<swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>\>のメール:
> > 
> > > ## 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.
> > 
> > This is not unrelated to pattern matching, this is the expected behavior of every pattern matching algorithm. The intent is to compile a switch-case tree down to (conceptually) a (hopefully minimal) if-else tree. You may be thinking of the behavior of switch in C and C-likes which is most certainly not pattern matching and includes behavior Swift has explicitly chosen to avoid like implicit fallthroughs.
> > 
> > > - `default:` case is required, even for expressions where a default case does not make sense.
> > 
> > Expression patterns may look to be covered “at first glance”, but the analysis required to prove that is equivalent to solving the halting problem in the general case. Further, your proposed idea has absolutely nothing to do with this.
> > 
> > > 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.
> > > 
> > > ```swift
> > > 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:
> > > 
> > > ```swift
> > > 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:
> > > 
> > > ```swift
> > > 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.
> > 
> > Again, this is not pattern matching.
> > 
> > > - A syntax that exactly aligns with the familiar, succinct, elegant, and understandable `switch` syntax.
> > 
> > A syntax that duplicates the existing if-case construct which, I should note, takes the same number of lines and roughly the same number of columns to express as your match. Even less, considering you unwrap in the if-case to exaggerate the example but not in the match.
> > 
> > > - 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.
> > > 
> > > ```swift
> > > 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.)
> > 
> > This is not boilerplate!
> > 
> > > ## 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:
> > > 
> > > ```swift
> > > 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:
> > > 
> > > ```swift
> > > 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"
> > > 
> > > ```
> > 
> > for i in 1...100 {  
> > &nbsp;&nbsp;var output = “”  
> > &nbsp;&nbsp;output += (i % 3 == 0) ? “Fizz” : “”  
> > &nbsp;&nbsp;output += (i % 5 == 0) ? “Buzz” : “”  
> > &nbsp;&nbsp;print(output.isEmpty ? “\(i)” : output)  
> > }
> > 
> > If control flow should branch multiple times, why not write just write it that way!
> > 
> > > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > > 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)

---

<div class="post-metadata">

**Author:** ![pkamb](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/pkamb/32/2500_2.png) [@pkamb](https://forums.swift.org/u/pkamb)\
**Post date:** [November 18, 2017, 7:30pm UTC](https://forums.swift.org/t/idea-pitch-add-match-statement-as-switch-like-syntax-alternative-to-if-case-pattern-matching/7095/8 "2017-11-18T19:30:14Z")

</div>

> alternative to `fallthrough` that would continue matching cases

Yes, that would be interesting to look into. Do you have any references or  
remember what the proposed keyword was called? Do any other languages have  
this feature?

> **···**
>
> On Sat, Nov 18, 2017 at 10:53 AM Kevin Nattinger \<swift@nattinger.net\> 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](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![knatt](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/knatt/32/22335_2.png) [@knatt](https://forums.swift.org/u/knatt)\
**Post date:** [November 18, 2017, 7:36pm UTC](https://forums.swift.org/t/idea-pitch-add-match-statement-as-switch-like-syntax-alternative-to-if-case-pattern-matching/7095/9 "2017-11-18T19:36:48Z")

</div>

Aha! I found a proposal Erica put forth about this a year and a while ago—

[https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160704/023955.html](https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160704/023955.html)

> **···**
>
> > On Nov 18, 2017, at 11:30 AM, Peter Kamb \<peterkamb@gmail.com\> wrote:
> > 
> > \> alternative to `fallthrough` that would continue matching cases
> > 
> > Yes, that would be interesting to look into. Do you have any references or remember what the proposed keyword was called? Do any other languages have this feature?
> > 
> > On Sat, Nov 18, 2017 at 10:53 AM Kevin Nattinger \<swift@nattinger.net \<mailto:swift@nattinger.net\>\> 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 \<mailto: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 \<mailto:swift-evolution@swift.org\>  
> > \> [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![pkamb](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/pkamb/32/2500_2.png) [@pkamb](https://forums.swift.org/u/pkamb)\
**Post date:** [November 18, 2017, 8:58pm UTC](https://forums.swift.org/t/idea-pitch-add-match-statement-as-switch-like-syntax-alternative-to-if-case-pattern-matching/7095/10 "2017-11-18T20:58:29Z")

</div>

I understand your point about multiple cases + the halting problem when  
applied to the implementation details of switch and pattern matching.

I think where we're missing is that what I'm envisioning would be syntactic  
sugar that would be de-sugared into a a line of single-case `if-case`  
statements. It would have nothing to do with matching multiple cases via  
the same mechanism as `switch`.

Motivation for the change vs. a line of if-case statements is a valid  
question of course :)

> **···**
>
> On Sat, Nov 18, 2017 at 10:48 AM, Robert Widmann \<devteam.codafi@gmail.com\> wrote:
> 
> > On Nov 18, 2017, at 4:42 AM, Peter Kamb \<peterkamb@gmail.com\> wrote:
> > 
> > Thanks for the review.
> > 
> > Motivation is essentially to provide a low-friction way to write `if case  
> > / if case / if case` statements that are all matching on the same  
> > expression, much in the same way that `switch` offers a way to write `if /  
> > else if / else` statements against the same expression.
> > 
> > That much I understand, but there’s no motivation as to why this kind of  
> > change needs to occur over a line of if-case statements. There isn’t  
> > anything in the pitch that demonstrates friction outside of a personal  
> > distaste for the syntax.
> > 
> > \> \> Only the \*first\* matching case is executed. Subsequent matching cases  
> > are not executed.  
> > \> This is not unrelated to pattern matching, this is the expected  
> > behavior of every pattern matching algorithm.
> > 
> > By that I meant that a string of `if case / if case / if case` statements,  
> > each individually matching against the same expression, would match and  
> > execute all 3 cases. A `switch` using the same 3 cases would execute only  
> > the first matching case. I took the "only first case" behavior to be a  
> > property of the \*switch\*, not of "pattern matching" in general? But perhaps  
> > I'm using the wrong terminology.
> > 
> > \> \> Allow filtering a single object through \*multiple\* cases of pattern  
> > matching, executing \*all\* cases that match.  
> > \> Again, this is not pattern matching.
> > 
> > A switch can have multiple cases that "would" match and execute, if you  
> > were to comment out the successful case above them. Why would a  
> > hypothetical statement that executed \*all\* matching cases, rather than just  
> > the first case, not be pattern matching? It wouldn't be a `switch`, for  
> > sure, but it seems like it would be just as much "pattern matching" as an  
> > `if-case`.
> > 
> > It is not pattern matching because it violates minimality - and we have a  
> > warning today when you write switches of overlapping patterns. Consider  
> > the semantics of pattern matching in the context of a tree - but it just so  
> > happens the nodes of this tree are your patterns and the branches, actual  
> > branches where control flow splits along the case-matrix. The goal is not  
> > to execute a find-all, the goal is to execute a find - exactly like a  
> > regular expression.
> > 
> > \> This is not boilerplate!
> > 
> > An `if case / if case` pair would not have the same concept of a shared  
> > `else/default` case used by a `switch` or `if/else`, which is why I said it  
> > would not be needed. `if-case` does not require an else/default. (Perhaps  
> > boilerplate was the wrong word, and I definitely didn't mean to suggest  
> > that switches should no longer require `default:`).
> > 
> > You misunderstand me. This is the same problem as the one I brought up  
> > before: You are subject to the halting problem in the general case. The  
> > catch-all clause isn’t just noise, it’s a fundamental necessity to  
> > guarantee sound semantics for this particular class of switch statements  
> > that, according to a fundamental barrier in computer science, cannot be  
> > checked for exhaustiveness.
> > 
> > On top of that, we cannot allow you to write an uncovered switch statement  
> > full of expression patterns because you would most-assuredly not handle all  
> > possible cases (suppose I extend your OptionSet with a new bit-pattern in a  
> > different module - your code will miscompile).
> > 
> > On Sat, Nov 18, 2017 at 12:19 AM, Robert Widmann \<devteam.codafi@gmail.com \> \> wrote:
> > 
> > > Having spent a lot of time with ‘switch’, I don’t understand any of the  
> > > motivations or corresponding justifications for this idea. Comments inline:
> > > 
> > > ~Robert Widmann
> > > 
> > > 2017/11/17 15:06、Peter Kamb via swift-evolution \<  
> > > swift-evolution@swift.org\>のメール:
> > > 
> > > ## 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.
> > > 
> > > This is not unrelated to pattern matching, this is the expected behavior  
> > > of every pattern matching algorithm. The intent is to compile a  
> > > switch-case tree down to (conceptually) a (hopefully minimal) if-else  
> > > tree. You may be thinking of the behavior of switch in C and C-likes which  
> > > is most certainly not pattern matching and includes behavior Swift has  
> > > explicitly chosen to avoid like implicit fallthroughs.
> > > 
> > > - `default:` case is required, even for expressions where a default case  
> > > does not make sense.
> > > 
> > > Expression patterns may look to be covered “at first glance”, but the  
> > > analysis required to prove that is equivalent to solving the halting  
> > > problem in the general case. Further, your proposed idea has absolutely  
> > > nothing to do with this.
> > > 
> > > 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.
> > > 
> > > ```swift
> > > 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:
> > > 
> > > ```swift
> > > 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:
> > > 
> > > ```swift
> > > 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.
> > > 
> > > Again, this is not pattern matching.
> > > 
> > > - A syntax that exactly aligns with the familiar, succinct, elegant, and  
> > > understandable `switch` syntax.
> > > 
> > > A syntax that duplicates the existing if-case construct which, I should  
> > > note, takes the same number of lines and roughly the same number of columns  
> > > to express as your match. Even less, considering you unwrap in the if-case  
> > > to exaggerate the example but not in the match.
> > > 
> > > - 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.
> > > 
> > > ```swift
> > > 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.)
> > > 
> > > This is not boilerplate!
> > > 
> > > ## 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:
> > > 
> > > ```swift
> > > 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:
> > > 
> > > ```swift
> > > 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"
> > > 
> > > ```
> > > 
> > > for i in 1...100 {  
> > > &nbsp;&nbsp;var output = “”  
> > > &nbsp;&nbsp;output += (i % 3 == 0) ? “Fizz” : “”  
> > > &nbsp;&nbsp;output += (i % 5 == 0) ? “Buzz” : “”  
> > > &nbsp;&nbsp;print(output.isEmpty ? “\(i)” : output)  
> > > }
> > > 
> > > If control flow should branch multiple times, \*why not write just write  
> > > it that way!\*
> > > 
> > > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > > swift-evolution mailing list  
> > > swift-evolution@swift.org  
> > > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![pkamb](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/pkamb/32/2500_2.png) [@pkamb](https://forums.swift.org/u/pkamb)\
**Post date:** [November 18, 2017, 9:12pm UTC](https://forums.swift.org/t/idea-pitch-add-match-statement-as-switch-like-syntax-alternative-to-if-case-pattern-matching/7095/11 "2017-11-18T21:12:03Z")

</div>

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.

> **···**
>
> On Sat, Nov 18, 2017 at 11:18 AM, Xiaodi Wu \<xiaodi.wu@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](https://lists.swift.org/mailman/listinfo/swift-evolution)
> > > 
> > > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > > swift-evolution mailing list  
> > > swift-evolution@swift.org  
> > > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [November 18, 2017, 9:43pm UTC](https://forums.swift.org/t/idea-pitch-add-match-statement-as-switch-like-syntax-alternative-to-if-case-pattern-matching/7095/12 "2017-11-18T21:43:14Z")

</div>

> 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 3:12 PM, Peter Kamb \<peterkamb@gmail.com\> wrote:
> 
> On Sat, Nov 18, 2017 at 11:18 AM, Xiaodi Wu \<xiaodi.wu@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](https://lists.swift.org/mailman/listinfo/swift-evolution)
> > > > 
> > > > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > > > swift-evolution mailing list  
> > > > swift-evolution@swift.org  
> > > > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![benjamin.g](https://avatars.discourse-cdn.com/v4/letter/b/9fc29f/32.png) [@benjamin.g](https://forums.swift.org/u/benjamin.g)\
**Post date:** [November 18, 2017, 10:25pm UTC](https://forums.swift.org/t/idea-pitch-add-match-statement-as-switch-like-syntax-alternative-to-if-case-pattern-matching/7095/13 "2017-11-18T22:25:54Z")

</div>

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

> **···**
>
> 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 \<peterkamb@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.wu@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](https://lists.swift.org/mailman/listinfo/swift-evolution)
> > > > > 
> > > > > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > > > > swift-evolution mailing list  
> > > > > 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  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [November 18, 2017, 10:47pm UTC](https://forums.swift.org/t/idea-pitch-add-match-statement-as-switch-like-syntax-alternative-to-if-case-pattern-matching/7095/14 "2017-11-18T22:47:41Z")

</div>

> 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...?

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 16:25 Benjamin G \<benjamin.garrigues@gmail.com\> wrote:
> 
> 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 \<peterkamb@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.wu@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](https://lists.swift.org/mailman/listinfo/swift-evolution)
> > > > > > 
> > > > > > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > > > > > swift-evolution mailing list  
> > > > > > 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  
> > > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![codafi](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/codafi/32/791_2.png) [@codafi](https://forums.swift.org/u/codafi)\
**Post date:** [November 19, 2017, 6:37am UTC](https://forums.swift.org/t/idea-pitch-add-match-statement-as-switch-like-syntax-alternative-to-if-case-pattern-matching/7095/15 "2017-11-19T06:37:40Z")

</div>

In regards to the problem in the root (using if-cases to do membership tests on option sets), the code given there involving thinking of the OptionSet as a sequence and iterating over it makes this far less likely to happen. I think this is a pattern that doesn't need syntax, it needs stdlib support at most. Perhaps an extension to OptionSet when the RawValue is known to be a sized integral type that does just that would clean up here.

~Robert Widmann

2017/11/18 17:25、Benjamin G via swift-evolution \<swift-evolution@swift.org\>のメール:

> **···**
>
> > 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
> > 
> > > 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 \<peterkamb@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.wu@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](https://lists.swift.org/mailman/listinfo/swift-evolution)
> > > > > > 
> > > > > > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > > > > > swift-evolution mailing list  
> > > > > > 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  
> > > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![benjamin.g](https://avatars.discourse-cdn.com/v4/letter/b/9fc29f/32.png) [@benjamin.g](https://forums.swift.org/u/benjamin.g)\
**Post date:** [November 19, 2017, 1:25pm UTC](https://forums.swift.org/t/idea-pitch-add-match-statement-as-switch-like-syntax-alternative-to-if-case-pattern-matching/7095/16 "2017-11-19T13:25:13Z")

</div>

> > 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.

> **···**
>
> > Le 18 nov. 2017 à 23:47, Xiaodi Wu \<xiaodi.wu@gmail.com\> a écrit :
> > 
> > > On Sat, Nov 18, 2017 at 16:25 Benjamin G \<benjamin.garrigues@gmail.com\> wrote:
> 
> > 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 \<peterkamb@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.wu@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](https://lists.swift.org/mailman/listinfo/swift-evolution)
> > > > > > > 
> > > > > > > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > > > > > > swift-evolution mailing list  
> > > > > > > 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  
> > > > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![pkamb](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/pkamb/32/2500_2.png) [@pkamb](https://forums.swift.org/u/pkamb)\
**Post date:** [February 27, 2018, 8:34pm UTC](https://forums.swift.org/t/idea-pitch-add-match-statement-as-switch-like-syntax-alternative-to-if-case-pattern-matching/7095/17 "2018-02-27T20:34:15Z")

</div>

linking the discourse thread for switch statement `continue`

> [@\[Pitch\] Introduce continue to switch statements](https://forums.swift.org/t/pitch-introduce-continue-to-switch-statements/3351/11):
>
> In the current Swift, absent `fallthrough`, the statement execution ends and no other statements are evaluated after the first match. With `fallthrough` the current clause executes and the next clause executes, and then the statement execution ends. With `continue`, the current clause executes and the switch continues searching for a matching pattern as if a pattern has not yet been matched. -- E 
> 
> > **···**
> >
> > On Jul 10, 2016, at 8:37 PM, Xiaodi Wu \<xiaodi.wu@gmail.com\> wrote: This is a neat ide…
