[Pitch] Introduce continue to switch statements


(Erica Sadun) #1

A quick pitch to introduce `continue` to switch statements. This would be additive and could not be considered for Swift 3.

-- E

Pitch: Introduce continue to Switch Statements

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#introduction>Introduction

This pitch completes the switch statement's control flow transfer suite by introducing continue. Doing so provides functionality that a large portion of newer developers expect from (but do not get from) fallthrough.

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#motivation>Motivation

Swift's fallthrough statement means "continue by executing the code defined in the next case clause". It has at least one solid use-case, which is demonstrated in this example <https://gist.github.com/stevestreza/2557dc5ec9e7c694d7ea>
Swift Evolution discussed removing fallthrough on-list in early December <https://lists.swift.org/pipermail/swift-evolution/2015-December/000226.html> We came to the consensus that fallthroughoffers sufficient utility to retain the feature in the language:

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#the-problem-with-fallthrough>The Problem with Fallthrough.

In Swift, fallthrough does not mean: "execute this case and then continue pattern matching", which is what many naive users expect. Given the following code where x is 5, they anticipate the function to print "5" and then "anything else". This is wrong. Swift prints "5" and then "6".

func test(x : Int) {
    switch x {
    case 5:
        print("5")
        fallthrough
    case 6:
        print("6")
    default:
        print("anything else")
    }
}
Fallthrough is better suited for situations like the following:

case simple where even more subconditions hold: ... do complex things ...; fallthrough
case simple where subconditions hold: ... do other things ...; fallthrough
case simple: ... do base things ...
This example produces a sieve where the most restrictive conditions execute specialized code and then execute code for less restrictive conditions.

Fallthrough cannot be used for situations like the following example:

case specialized situation 1: ... code specific to situation 1 ...; fallthrough
case specialized situation 2: ... code specific to situation 2 ...; fallthrough
case specialized situation 3: ... code specific to situation 3 ...; fallthrough
case general: ... general code applicable as well to the three specialized situations ...
Those coming from C-like languages might have the insight to expect (wrongly, it should be noted) "5", then "6", then "anything else", which is what you'd get with the following flawed C-ish code, where case statements are missing break.

int x = 5;
switch (x) {
    case 5: NSLog(@"5"); // no break;
    case 6: NSLog(@"6"); // no break;
    default: NSLog(@"anything else");
}
Swift-style switch statements are more powerful and general than C-style switch statements. While I do not endorse C-style switch statements, I do think there's a case to be made for continue, which would mean "continue pattern matching". It would look like this:

case specialized situation 1: ... code specific to situation 1 ...; continue
case specialized situation 2: ... code specific to situation 2 ...; continue
case specialized situation 3: ... code specific to situation 3 ...; continue
case general: ... general code applicable as well to the three specialized situations ...
In this example, code that matched general might execute any of the three specialized subconditions as well but would not have to fall through each case. So if a pattern matched scenarios 1 and 3, it would execute those cases and the general case, but not scenario 2.

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#the-advantages-of-continue>The advantages of continue

If adopted, continue allows code to execute multiple matching patterns
It naturally reduces code redundancy where fallthrough cannot be used but code applies to multiple cases (such as the 1, 3, and general example above).
It uses an existing control flow transfer keyword, using it in a reasonably harmonious application that isn't that far out of step with how the keyword is used in other parts of the language.
<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#detailed-design>Detailed Design

In the current design, switch statements support subset of control flow transfer:

control-transfer-statement ‚Üí break-statement
control-transfer-statement ‚Üí fallthrough-statement
control-transfer-statement ‚Üí return-statement
control-transfer-statement ‚Üí throw-statement
Notably missing is "continue", which this proposal would adopt.

control-transfer-statement ‚Üí continue-statement
The definition of continue in a switch statement would mean "after executing the previous statements in this case clause, continue pattern matching the remaining cases until a match or default is found.

continue could either be disallowed in the final case (typically default) or could be ignored if included.

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#impact-on-existing-code>Impact on Existing Code

None.

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#alternatives-considered>Alternatives Considered

Not adopting this idea


(Xiaodi Wu) #2

This is a neat idea, and I think a very sensible way to extend the
language. I worry only a little about the following:

Currently, unless preceded immediately by the keyword `fallthrough`, a
condition implicitly excludes all previous conditions. That is, if I write
`switch .. { case a: ...; case b: ...; case c: ... }`, my condition `c` is
really `!a && !b && c`. With more flexible control flow within a switch
statement, reasoning about what cases are matched by any particular
condition after the first becomes increasingly difficult.

···

On Sun, Jul 10, 2016 at 9:27 PM, Erica Sadun via swift-evolution < swift-evolution@swift.org> wrote:

A quick pitch to introduce `continue` to switch statements. This would be
additive and could not be considered for Swift 3.

-- E

Pitch: Introduce continue to Switch Statements
<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#introduction>
Introduction

This pitch completes the switch statement's control flow transfer suite by
introducing continue. Doing so provides functionality that a large
portion of newer developers expect from (but do not get from) fallthrough.
<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#motivation>
Motivation

Swift's fallthrough statement means "continue by executing the code
defined in the next case clause". It has at least one solid use-case, which
is demonstrated in this example
<https://gist.github.com/stevestreza/2557dc5ec9e7c694d7ea>

Swift Evolution discussed removing fallthrough on-list in early December
<https://lists.swift.org/pipermail/swift-evolution/2015-December/000226.html> We
came to the consensus that fallthroughoffers sufficient utility to retain
the feature in the language:

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#the-problem-with-fallthrough>The
Problem with Fallthrough.

In Swift, fallthrough does not mean: "execute this case and then continue
pattern matching", which is what many naive users expect. Given the
following code where x is 5, they anticipate the function to print "5"
and then "anything else". This is wrong. Swift prints "5" and then "6".

func test(x : Int) {
    switch x {
    case 5:
        print("5")
        fallthrough
    case 6:
        print("6")
    default:
        print("anything else")
    }
}

Fallthrough is better suited for situations like the following:

case simple where even more subconditions hold: ... do complex things ...; fallthrough
case simple where subconditions hold: ... do other things ...; fallthrough
case simple: ... do base things ...

This example produces a sieve where the most restrictive conditions
execute specialized code and then execute code for less restrictive
conditions.

Fallthrough *cannot* be used for situations like the following example:

case specialized situation 1: ... code specific to situation 1 ...; fallthrough
case specialized situation 2: ... code specific to situation 2 ...; fallthrough
case specialized situation 3: ... code specific to situation 3 ...; fallthrough
case general: ... general code applicable as well to the three specialized situations ...

Those coming from C-like languages might have the insight to expect
(wrongly, it should be noted) "5", then "6", then "anything else", which is
what you'd get with the following flawed C-ish code, where case statements
are missing break.

int x = 5;
switch (x) {
    case 5: NSLog(@"5"); // no break;
    case 6: NSLog(@"6"); // no break;
    default: NSLog(@"anything else");
}

Swift-style switch statements are more powerful and general than C-style
switch statements. While I do not endorse C-style switch statements, I do
think there's a case to be made for continue, which would mean "continue
pattern matching". It would look like this:

case specialized situation 1: ... code specific to situation 1 ...; continue
case specialized situation 2: ... code specific to situation 2 ...; continue
case specialized situation 3: ... code specific to situation 3 ...; continue
case general: ... general code applicable as well to the three specialized situations ...

In this example, code that matched general might execute any of the three
specialized subconditions as well but would not have to fall through each
case. So if a pattern matched scenarios 1 and 3, it would execute those
cases and the general case, but not scenario 2.

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#the-advantages-of-continue>The
advantages of continue

   - If adopted, continue allows code to execute multiple matching
   patterns
   - It naturally reduces code redundancy where fallthrough cannot be
   used but code applies to multiple cases (such as the 1, 3, and general
   example above).
   - It uses an existing control flow transfer keyword, using it in a
   reasonably harmonious application that isn't that far out of step with how
   the keyword is used in other parts of the language.

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#detailed-design>Detailed
Design

In the current design, switch statements support subset of control flow
transfer:

control-transfer-statement ‚Üí break-statement
control-transfer-statement ‚Üí fallthrough-statement
control-transfer-statement ‚Üí return-statement
control-transfer-statement ‚Üí throw-statement

Notably missing is "continue", which this proposal would adopt.

control-transfer-statement ‚Üí continue-statement

The definition of continue in a switch statement would mean "after
executing the previous statements in this case clause, continue pattern
matching the remaining cases until a match or default is found.

continue could either be disallowed in the final case (typically default)
or could be ignored if included.

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#impact-on-existing-code>Impact
on Existing Code

None.

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#alternatives-considered>Alternatives
Considered
Not adopting this idea

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Psycho Hedgehog) #3

This is a great feature, and this is something that would allow the execution of multiple case statements that fallthrough does not currently allow. For example in today's world this is not allowed:

func blah(point: CGPoint) {
    switch (point.x, point.y) {
    case (let x, _) where x > 10:
        print("\(x)")
        fallthrough // error 'fallthrough' cannot transfer control to a case label that declares variables
    case (_, let y) where y > 10:
        print("\(y)")
    case (let x, let y) where x <= 10 && y <= 10:
        print("the point is too close from the border")
    }
}

Using continue as proposed by erica would allow both patterns at the top to be evaluated and have the ability to check x and y independently.

Also this raises in my opinion an interesting point. I think along this proposal it would be great to have another type of case that would only run if no other pattern could be recognized. I'm not sure how to call it though.

···

Le 10 juil. 2016 à 19:27, Erica Sadun via swift-evolution <swift-evolution@swift.org> a écrit :

A quick pitch to introduce `continue` to switch statements. This would be additive and could not be considered for Swift 3.

-- E

Pitch: Introduce continue to Switch Statements

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#introduction>Introduction

This pitch completes the switch statement's control flow transfer suite by introducing continue. Doing so provides functionality that a large portion of newer developers expect from (but do not get from) fallthrough.

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#motivation>Motivation

Swift's fallthrough statement means "continue by executing the code defined in the next case clause". It has at least one solid use-case, which is demonstrated in this example <https://gist.github.com/stevestreza/2557dc5ec9e7c694d7ea>
Swift Evolution discussed removing fallthrough on-list in early December <https://lists.swift.org/pipermail/swift-evolution/2015-December/000226.html> We came to the consensus that fallthroughoffers sufficient utility to retain the feature in the language:

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#the-problem-with-fallthrough>The Problem with Fallthrough.

In Swift, fallthrough does not mean: "execute this case and then continue pattern matching", which is what many naive users expect. Given the following code where x is 5, they anticipate the function to print "5" and then "anything else". This is wrong. Swift prints "5" and then "6".

func test(x : Int) {
    switch x {
    case 5:
        print("5")
        fallthrough
    case 6:
        print("6")
    default:
        print("anything else")
    }
}
Fallthrough is better suited for situations like the following:

case simple where even more subconditions hold: ... do complex things ...; fallthrough
case simple where subconditions hold: ... do other things ...; fallthrough
case simple: ... do base things ...
This example produces a sieve where the most restrictive conditions execute specialized code and then execute code for less restrictive conditions.

Fallthrough cannot be used for situations like the following example:

case specialized situation 1: ... code specific to situation 1 ...; fallthrough
case specialized situation 2: ... code specific to situation 2 ...; fallthrough
case specialized situation 3: ... code specific to situation 3 ...; fallthrough
case general: ... general code applicable as well to the three specialized situations ...
Those coming from C-like languages might have the insight to expect (wrongly, it should be noted) "5", then "6", then "anything else", which is what you'd get with the following flawed C-ish code, where case statements are missing break.

int x = 5;
switch (x) {
    case 5: NSLog(@"5"); // no break;
    case 6: NSLog(@"6"); // no break;
    default: NSLog(@"anything else");
}
Swift-style switch statements are more powerful and general than C-style switch statements. While I do not endorse C-style switch statements, I do think there's a case to be made for continue, which would mean "continue pattern matching". It would look like this:

case specialized situation 1: ... code specific to situation 1 ...; continue
case specialized situation 2: ... code specific to situation 2 ...; continue
case specialized situation 3: ... code specific to situation 3 ...; continue
case general: ... general code applicable as well to the three specialized situations ...
In this example, code that matched general might execute any of the three specialized subconditions as well but would not have to fall through each case. So if a pattern matched scenarios 1 and 3, it would execute those cases and the general case, but not scenario 2.

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#the-advantages-of-continue>The advantages of continue

If adopted, continue allows code to execute multiple matching patterns
It naturally reduces code redundancy where fallthrough cannot be used but code applies to multiple cases (such as the 1, 3, and general example above).
It uses an existing control flow transfer keyword, using it in a reasonably harmonious application that isn't that far out of step with how the keyword is used in other parts of the language.
<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#detailed-design>Detailed Design

In the current design, switch statements support subset of control flow transfer:

control-transfer-statement ‚Üí break-statement
control-transfer-statement ‚Üí fallthrough-statement
control-transfer-statement ‚Üí return-statement
control-transfer-statement ‚Üí throw-statement
Notably missing is "continue", which this proposal would adopt.

control-transfer-statement ‚Üí continue-statement
The definition of continue in a switch statement would mean "after executing the previous statements in this case clause, continue pattern matching the remaining cases until a match or default is found.

continue could either be disallowed in the final case (typically default) or could be ignored if included.

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#impact-on-existing-code>Impact on Existing Code

None.

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#alternatives-considered>Alternatives Considered

Not adopting this idea
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(G B) #4

I like this idea.

Remember that `continue` can typically take an optional argument that allows a type of ‚Äúgoto‚ÄĚ functionality. Would it work to allow the `continue` target to be a labeled `case`? This could allow for some rather sophisticated logic without needing to duplicate a lot of code and without needing to nest the switch in a loop-- especially if switching on a `var`.

An `enum` and a `switch` with targeted `continues` would make for a nice, clean state machine by updating the state in the `case` and then jumping to the right point in the selection logic. The target could be, but wouldn’t need to be the top of the `switch`.

I’ve long thought that `fallthrough` should prefer a target to avoid the problems of accidentally slipping a `case` in between the `case` you’re falling out of and the `case` you’d meant to fall into.

I’m not sure what the right syntax would be for the target label if the `case` uses a colon for punctuation. I suppose the label could be the `case`, but that seems verbose.

The ability to insert labels inside the switch would be another advantage of wrapping the `case` statements in curly brackets though.

···

On Jul 10, 2016, at 19:27 , Erica Sadun via swift-evolution <swift-evolution@swift.org> wrote:

A quick pitch to introduce `continue` to switch statements. This would be additive and could not be considered for Swift 3.

-- E

Pitch: Introduce continue to Switch Statements

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#introduction>Introduction

This pitch completes the switch statement's control flow transfer suite by introducing continue. Doing so provides functionality that a large portion of newer developers expect from (but do not get from) fallthrough.

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#motivation>Motivation

Swift's fallthrough statement means "continue by executing the code defined in the next case clause". It has at least one solid use-case, which is demonstrated in this example <https://gist.github.com/stevestreza/2557dc5ec9e7c694d7ea>
Swift Evolution discussed removing fallthrough on-list in early December <https://lists.swift.org/pipermail/swift-evolution/2015-December/000226.html> We came to the consensus that fallthroughoffers sufficient utility to retain the feature in the language:

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#the-problem-with-fallthrough>The Problem with Fallthrough.

In Swift, fallthrough does not mean: "execute this case and then continue pattern matching", which is what many naive users expect. Given the following code where x is 5, they anticipate the function to print "5" and then "anything else". This is wrong. Swift prints "5" and then "6".

func test(x : Int) {
    switch x {
    case 5:
        print("5")
        fallthrough
    case 6:
        print("6")
    default:
        print("anything else")
    }
}
Fallthrough is better suited for situations like the following:

case simple where even more subconditions hold: ... do complex things ...; fallthrough
case simple where subconditions hold: ... do other things ...; fallthrough
case simple: ... do base things ...
This example produces a sieve where the most restrictive conditions execute specialized code and then execute code for less restrictive conditions.

Fallthrough cannot be used for situations like the following example:

case specialized situation 1: ... code specific to situation 1 ...; fallthrough
case specialized situation 2: ... code specific to situation 2 ...; fallthrough
case specialized situation 3: ... code specific to situation 3 ...; fallthrough
case general: ... general code applicable as well to the three specialized situations ...
Those coming from C-like languages might have the insight to expect (wrongly, it should be noted) "5", then "6", then "anything else", which is what you'd get with the following flawed C-ish code, where case statements are missing break.

int x = 5;
switch (x) {
    case 5: NSLog(@"5"); // no break;
    case 6: NSLog(@"6"); // no break;
    default: NSLog(@"anything else");
}
Swift-style switch statements are more powerful and general than C-style switch statements. While I do not endorse C-style switch statements, I do think there's a case to be made for continue, which would mean "continue pattern matching". It would look like this:

case specialized situation 1: ... code specific to situation 1 ...; continue
case specialized situation 2: ... code specific to situation 2 ...; continue
case specialized situation 3: ... code specific to situation 3 ...; continue
case general: ... general code applicable as well to the three specialized situations ...
In this example, code that matched general might execute any of the three specialized subconditions as well but would not have to fall through each case. So if a pattern matched scenarios 1 and 3, it would execute those cases and the general case, but not scenario 2.

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#the-advantages-of-continue>The advantages of continue

If adopted, continue allows code to execute multiple matching patterns
It naturally reduces code redundancy where fallthrough cannot be used but code applies to multiple cases (such as the 1, 3, and general example above).
It uses an existing control flow transfer keyword, using it in a reasonably harmonious application that isn't that far out of step with how the keyword is used in other parts of the language.
<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#detailed-design>Detailed Design

In the current design, switch statements support subset of control flow transfer:

control-transfer-statement ‚Üí break-statement
control-transfer-statement ‚Üí fallthrough-statement
control-transfer-statement ‚Üí return-statement
control-transfer-statement ‚Üí throw-statement
Notably missing is "continue", which this proposal would adopt.

control-transfer-statement ‚Üí continue-statement
The definition of continue in a switch statement would mean "after executing the previous statements in this case clause, continue pattern matching the remaining cases until a match or default is found.

continue could either be disallowed in the final case (typically default) or could be ignored if included.

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#impact-on-existing-code>Impact on Existing Code

None.

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#alternatives-considered>Alternatives Considered

Not adopting this idea
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Taras Zakharko) #5

There is possible impact on existing code: a switch statement inside a loop, that contains a continue.

‚ÄĒ Taras

···

On 11 Jul 2016, at 04:27, Erica Sadun via swift-evolution <swift-evolution@swift.org> wrote:

A quick pitch to introduce `continue` to switch statements. This would be additive and could not be considered for Swift 3.

-- E

Pitch: Introduce continue to Switch Statements

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#introduction>Introduction

This pitch completes the switch statement's control flow transfer suite by introducing continue. Doing so provides functionality that a large portion of newer developers expect from (but do not get from) fallthrough.

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#motivation>Motivation

Swift's fallthrough statement means "continue by executing the code defined in the next case clause". It has at least one solid use-case, which is demonstrated in this example <https://gist.github.com/stevestreza/2557dc5ec9e7c694d7ea>
Swift Evolution discussed removing fallthrough on-list in early December <https://lists.swift.org/pipermail/swift-evolution/2015-December/000226.html> We came to the consensus that fallthroughoffers sufficient utility to retain the feature in the language:

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#the-problem-with-fallthrough>The Problem with Fallthrough.

In Swift, fallthrough does not mean: "execute this case and then continue pattern matching", which is what many naive users expect. Given the following code where x is 5, they anticipate the function to print "5" and then "anything else". This is wrong. Swift prints "5" and then "6".

func test(x : Int) {
    switch x {
    case 5:
        print("5")
        fallthrough
    case 6:
        print("6")
    default:
        print("anything else")
    }
}
Fallthrough is better suited for situations like the following:

case simple where even more subconditions hold: ... do complex things ...; fallthrough
case simple where subconditions hold: ... do other things ...; fallthrough
case simple: ... do base things ...
This example produces a sieve where the most restrictive conditions execute specialized code and then execute code for less restrictive conditions.

Fallthrough cannot be used for situations like the following example:

case specialized situation 1: ... code specific to situation 1 ...; fallthrough
case specialized situation 2: ... code specific to situation 2 ...; fallthrough
case specialized situation 3: ... code specific to situation 3 ...; fallthrough
case general: ... general code applicable as well to the three specialized situations ...
Those coming from C-like languages might have the insight to expect (wrongly, it should be noted) "5", then "6", then "anything else", which is what you'd get with the following flawed C-ish code, where case statements are missing break.

int x = 5;
switch (x) {
    case 5: NSLog(@"5"); // no break;
    case 6: NSLog(@"6"); // no break;
    default: NSLog(@"anything else");
}
Swift-style switch statements are more powerful and general than C-style switch statements. While I do not endorse C-style switch statements, I do think there's a case to be made for continue, which would mean "continue pattern matching". It would look like this:

case specialized situation 1: ... code specific to situation 1 ...; continue
case specialized situation 2: ... code specific to situation 2 ...; continue
case specialized situation 3: ... code specific to situation 3 ...; continue
case general: ... general code applicable as well to the three specialized situations ...
In this example, code that matched general might execute any of the three specialized subconditions as well but would not have to fall through each case. So if a pattern matched scenarios 1 and 3, it would execute those cases and the general case, but not scenario 2.

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#the-advantages-of-continue>The advantages of continue

If adopted, continue allows code to execute multiple matching patterns
It naturally reduces code redundancy where fallthrough cannot be used but code applies to multiple cases (such as the 1, 3, and general example above).
It uses an existing control flow transfer keyword, using it in a reasonably harmonious application that isn't that far out of step with how the keyword is used in other parts of the language.
<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#detailed-design>Detailed Design

In the current design, switch statements support subset of control flow transfer:

control-transfer-statement ‚Üí break-statement
control-transfer-statement ‚Üí fallthrough-statement
control-transfer-statement ‚Üí return-statement
control-transfer-statement ‚Üí throw-statement
Notably missing is "continue", which this proposal would adopt.

control-transfer-statement ‚Üí continue-statement
The definition of continue in a switch statement would mean "after executing the previous statements in this case clause, continue pattern matching the remaining cases until a match or default is found.

continue could either be disallowed in the final case (typically default) or could be ignored if included.

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#impact-on-existing-code>Impact on Existing Code

None.

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#alternatives-considered>Alternatives Considered

Not adopting this idea
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Rob Mayoff) #6

Just to be clear, under your proposal, what does the following program
print? Can you make an argument in favor of your interpretation?

    var x = 1
    switch x {
    case 1:
        print("one")
        x = 2
        continue
    case 2:
        print("two")
    default:
        break
    }


(Jacopo Andrea Giola) #7

Here we go again :slight_smile:

I’m obviously supporting this proposal, like the first one we had tried to pass at the beginning of the swift evolution mailing list, even if in those times, we try to completely replace the fallthrough keyword with a new one.

I continue to have a draft of that proposal on gist https://gist.github.com/JGiola/f735212789bf2f697847

Instead of continue we put out a fallto keyword that must explicit state the case where we want to go at the end of that case, but this solution is more clean and simple to reasoning with and use a well stated keyword used in others flow statements.

- Jacopo

···

On 11 Jul 2016, at 04:27, Erica Sadun via swift-evolution <swift-evolution@swift.org> wrote:

A quick pitch to introduce `continue` to switch statements. This would be additive and could not be considered for Swift 3.

-- E

Pitch: Introduce continue to Switch Statements

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#introduction>Introduction

This pitch completes the switch statement's control flow transfer suite by introducing continue. Doing so provides functionality that a large portion of newer developers expect from (but do not get from) fallthrough.

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#motivation>Motivation

Swift's fallthrough statement means "continue by executing the code defined in the next case clause". It has at least one solid use-case, which is demonstrated in this example <https://gist.github.com/stevestreza/2557dc5ec9e7c694d7ea>
Swift Evolution discussed removing fallthrough on-list in early December <https://lists.swift.org/pipermail/swift-evolution/2015-December/000226.html> We came to the consensus that fallthroughoffers sufficient utility to retain the feature in the language:

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#the-problem-with-fallthrough>The Problem with Fallthrough.

In Swift, fallthrough does not mean: "execute this case and then continue pattern matching", which is what many naive users expect. Given the following code where x is 5, they anticipate the function to print "5" and then "anything else". This is wrong. Swift prints "5" and then "6".

func test(x : Int) {
    switch x {
    case 5:
        print("5")
        fallthrough
    case 6:
        print("6")
    default:
        print("anything else")
    }
}
Fallthrough is better suited for situations like the following:

case simple where even more subconditions hold: ... do complex things ...; fallthrough
case simple where subconditions hold: ... do other things ...; fallthrough
case simple: ... do base things ...
This example produces a sieve where the most restrictive conditions execute specialized code and then execute code for less restrictive conditions.

Fallthrough cannot be used for situations like the following example:

case specialized situation 1: ... code specific to situation 1 ...; fallthrough
case specialized situation 2: ... code specific to situation 2 ...; fallthrough
case specialized situation 3: ... code specific to situation 3 ...; fallthrough
case general: ... general code applicable as well to the three specialized situations ...
Those coming from C-like languages might have the insight to expect (wrongly, it should be noted) "5", then "6", then "anything else", which is what you'd get with the following flawed C-ish code, where case statements are missing break.

int x = 5;
switch (x) {
    case 5: NSLog(@"5"); // no break;
    case 6: NSLog(@"6"); // no break;
    default: NSLog(@"anything else");
}
Swift-style switch statements are more powerful and general than C-style switch statements. While I do not endorse C-style switch statements, I do think there's a case to be made for continue, which would mean "continue pattern matching". It would look like this:

case specialized situation 1: ... code specific to situation 1 ...; continue
case specialized situation 2: ... code specific to situation 2 ...; continue
case specialized situation 3: ... code specific to situation 3 ...; continue
case general: ... general code applicable as well to the three specialized situations ...
In this example, code that matched general might execute any of the three specialized subconditions as well but would not have to fall through each case. So if a pattern matched scenarios 1 and 3, it would execute those cases and the general case, but not scenario 2.

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#the-advantages-of-continue>The advantages of continue

If adopted, continue allows code to execute multiple matching patterns
It naturally reduces code redundancy where fallthrough cannot be used but code applies to multiple cases (such as the 1, 3, and general example above).
It uses an existing control flow transfer keyword, using it in a reasonably harmonious application that isn't that far out of step with how the keyword is used in other parts of the language.
<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#detailed-design>Detailed Design

In the current design, switch statements support subset of control flow transfer:

control-transfer-statement ‚Üí break-statement
control-transfer-statement ‚Üí fallthrough-statement
control-transfer-statement ‚Üí return-statement
control-transfer-statement ‚Üí throw-statement
Notably missing is "continue", which this proposal would adopt.

control-transfer-statement ‚Üí continue-statement
The definition of continue in a switch statement would mean "after executing the previous statements in this case clause, continue pattern matching the remaining cases until a match or default is found.

continue could either be disallowed in the final case (typically default) or could be ignored if included.

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#impact-on-existing-code>Impact on Existing Code

None.

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#alternatives-considered>Alternatives Considered

Not adopting this idea
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Haravikk) #8

I'm a bit undecided about this feature, as I think it's harder to read the switch statement. For example, with this new feature I could write something like so:

  switch x {
    case 1:
      print("1")
    case 2:
      print("2")
      continue
    case 3:
      print("3")
      continue
    default:
      print("base")
  }

But right now I can achieve this with the following:

  switch x {
    case 1:
      print("1")
    default:
      switch x {
        case 2:
          print("2")
        case 3:
          print("3")
      }
      print("base")
  }

Personally I prefer the latter; it isn't actually much more code, though it's certainly more visually noisy, but it's very explicit about what's going on, and avoids having to consider which cases will be reconsidered as the nested switch makes it very clear what it covers. Of course very complex cases may require more nesting, so become even less pretty, but personally I think the grouping outweighs this overall as it visually narrows the focus.

I wonder if perhaps there might be a way to instead simplify nested switches when operating on the same value? Is there a good real-world example that shows where a continue keyword would have clear advantage over nesting?

···

On 11 Jul 2016, at 03:27, Erica Sadun via swift-evolution <swift-evolution@swift.org> wrote:

A quick pitch to introduce `continue` to switch statements. This would be additive and could not be considered for Swift 3.

-- E

Pitch: Introduce continue to Switch Statements

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#introduction>Introduction

This pitch completes the switch statement's control flow transfer suite by introducing continue. Doing so provides functionality that a large portion of newer developers expect from (but do not get from) fallthrough.

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#motivation>Motivation

Swift's fallthrough statement means "continue by executing the code defined in the next case clause". It has at least one solid use-case, which is demonstrated in this example <https://gist.github.com/stevestreza/2557dc5ec9e7c694d7ea>
Swift Evolution discussed removing fallthrough on-list in early December <https://lists.swift.org/pipermail/swift-evolution/2015-December/000226.html> We came to the consensus that fallthroughoffers sufficient utility to retain the feature in the language:

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#the-problem-with-fallthrough>The Problem with Fallthrough.

In Swift, fallthrough does not mean: "execute this case and then continue pattern matching", which is what many naive users expect. Given the following code where x is 5, they anticipate the function to print "5" and then "anything else". This is wrong. Swift prints "5" and then "6".

func test(x : Int) {
    switch x {
    case 5:
        print("5")
        fallthrough
    case 6:
        print("6")
    default:
        print("anything else")
    }
}
Fallthrough is better suited for situations like the following:

case simple where even more subconditions hold: ... do complex things ...; fallthrough
case simple where subconditions hold: ... do other things ...; fallthrough
case simple: ... do base things ...
This example produces a sieve where the most restrictive conditions execute specialized code and then execute code for less restrictive conditions.

Fallthrough cannot be used for situations like the following example:

case specialized situation 1: ... code specific to situation 1 ...; fallthrough
case specialized situation 2: ... code specific to situation 2 ...; fallthrough
case specialized situation 3: ... code specific to situation 3 ...; fallthrough
case general: ... general code applicable as well to the three specialized situations ...
Those coming from C-like languages might have the insight to expect (wrongly, it should be noted) "5", then "6", then "anything else", which is what you'd get with the following flawed C-ish code, where case statements are missing break.

int x = 5;
switch (x) {
    case 5: NSLog(@"5"); // no break;
    case 6: NSLog(@"6"); // no break;
    default: NSLog(@"anything else");
}
Swift-style switch statements are more powerful and general than C-style switch statements. While I do not endorse C-style switch statements, I do think there's a case to be made for continue, which would mean "continue pattern matching". It would look like this:

case specialized situation 1: ... code specific to situation 1 ...; continue
case specialized situation 2: ... code specific to situation 2 ...; continue
case specialized situation 3: ... code specific to situation 3 ...; continue
case general: ... general code applicable as well to the three specialized situations ...
In this example, code that matched general might execute any of the three specialized subconditions as well but would not have to fall through each case. So if a pattern matched scenarios 1 and 3, it would execute those cases and the general case, but not scenario 2.

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#the-advantages-of-continue>The advantages of continue

If adopted, continue allows code to execute multiple matching patterns
It naturally reduces code redundancy where fallthrough cannot be used but code applies to multiple cases (such as the 1, 3, and general example above).
It uses an existing control flow transfer keyword, using it in a reasonably harmonious application that isn't that far out of step with how the keyword is used in other parts of the language.
<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#detailed-design>Detailed Design

In the current design, switch statements support subset of control flow transfer:

control-transfer-statement ‚Üí break-statement
control-transfer-statement ‚Üí fallthrough-statement
control-transfer-statement ‚Üí return-statement
control-transfer-statement ‚Üí throw-statement
Notably missing is "continue", which this proposal would adopt.

control-transfer-statement ‚Üí continue-statement
The definition of continue in a switch statement would mean "after executing the previous statements in this case clause, continue pattern matching the remaining cases until a match or default is found.

continue could either be disallowed in the final case (typically default) or could be ignored if included.

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#impact-on-existing-code>Impact on Existing Code

None.

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#alternatives-considered>Alternatives Considered

Not adopting this idea
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Chris Lattner) #9

As for all of the other additive changes, I would strongly prefer you to *wait* on even proposing or discussing these things until after the Swift 3.0 evolution cycle is done. Not only is it distracting for the community, but the core team and many others won’t be be able to even read the thread or the responses, thus your discussion cycle will be lacking key input.

On this topic, we specifically discussed this when labeled breaks were being designed, and when they were expanded to ‚Äúdo‚ÄĚ in Swift 2. We specifically decided to allow break but not continue, because we didn‚Äôt want these control flow statements to be ‚Äúanother way to spell a loop‚ÄĚ.

-Chris

···

On Jul 10, 2016, at 7:27 PM, Erica Sadun via swift-evolution <swift-evolution@swift.org> wrote:

A quick pitch to introduce `continue` to switch statements. This would be additive and could not be considered for Swift 3.

-- E

Pitch: Introduce continue to Switch Statements

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#introduction>Introduction

This pitch completes the switch statement's control flow transfer suite by introducing continue. Doing so provides functionality that a large portion of newer developers expect from (but do not get from) fallthrough.


(Erica Sadun) #10

A switch statement within a loop may be broken by the introduction of `continue` semantics. To fix, the loop must be labeled and the `continue` must use that label to differentiate between switch continuation and loop continuation.

Updated gist: https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a

-- E

···

On Jul 10, 2016, at 8:36 PM, Taras Zakharko <taras.zakharko@uzh.ch> wrote:

There is possible impact on existing code: a switch statement inside a loop, that contains a continue.

‚ÄĒ Taras


(Erica Sadun) #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 idea, and I think a very sensible way to extend the language. I worry only a little about the following:

Currently, unless preceded immediately by the keyword `fallthrough`, a condition implicitly excludes all previous conditions. That is, if I write `switch .. { case a: ...; case b: ...; case c: ... }`, my condition `c` is really `!a && !b && c`. With more flexible control flow within a switch statement, reasoning about what cases are matched by any particular condition after the first becomes increasingly difficult.


[Idea] [Pitch] Add `match` statement as `switch`-like syntax alternative to `if case` pattern matching
(Erica Sadun) #12

The switch statement is defined as:

switch-statement ‚Üí switch expression {switch-cases*}

I'd imagine this means the expression is evaluated once, e.g.:

switch 2 + 3 {
case 5: print("Five!")
default: break
}

So I'm more likely to expect "one" than "one"/"two". I would defer this question
to the core team for a better answer.

-- E

···

On Jul 11, 2016, at 7:27 AM, Rob Mayoff <mayoff@dqd.com> wrote:

Just to be clear, under your proposal, what does the following program
print? Can you make an argument in favor of your interpretation?

   var x = 1
   switch x {
   case 1:
       print("one")
       x = 2
       continue
   case 2:
       print("two")
   default:
       break
   }


(Ross O'Brien) #13

I'm in favour of this concept being available in Swift, but it does need to
make a clear distinction somewhere between a case which matches anything
(and can catch any fallthrough/continue) and a case which matches none of
the above. I don't know whether we need to introduce an explicit term for
this, or whether we make this the distinction between 'case _:' and
'default:' (with the side-effect that we can now justify 'default' in the
language).

For example: let's use this switch to play fizzbuzz.

switch value
{
  case x where x % 3 == 0:
    print("fizz")
    continue
  case x where x % 5 == 0:
    print("buzz")
  default:
    print(value)
}

I know this is a trivial example, but it's also a frequent example used to
teach switch to programmers.
The keywords in play are 'continue' and 'default'. A multiple of 5 but not
3 will print 'buzz' and be done. A multiple of 3 and 5 will print 'fizz
buzz'. Any number not a multiple of 3 or 5 will say its value. Crucially, a
multiple of 3 but not 5 will say fizz, won't say buzz, and won't say the
number itself - whereas if we used 'case _', it would say fizz and then the
number itself.

···

On Mon, Jul 11, 2016 at 9:33 AM, Jacopo Andrea Giola via swift-evolution < swift-evolution@swift.org> wrote:

Here we go again :slight_smile:

I’m obviously supporting this proposal, like the first one we had tried to
pass at the beginning of the swift evolution mailing list, even if in those
times, we try to completely replace the fallthrough keyword with a new one.

I continue to have a draft of that proposal on gist
https://gist.github.com/JGiola/f735212789bf2f697847

Instead of continue we put out a fallto keyword that must explicit state
the case where we want to go at the end of that case, but this solution is
more clean and simple to reasoning with and use a well stated keyword used
in others flow statements.

- Jacopo

On 11 Jul 2016, at 04:27, Erica Sadun via swift-evolution < > swift-evolution@swift.org> wrote:

A quick pitch to introduce `continue` to switch statements. This would be
additive and could not be considered for Swift 3.

-- E

Pitch: Introduce continue to Switch Statements
<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#introduction>
Introduction

This pitch completes the switch statement's control flow transfer suite by
introducing continue. Doing so provides functionality that a large
portion of newer developers expect from (but do not get from) fallthrough.
<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#motivation>
Motivation

Swift's fallthrough statement means "continue by executing the code
defined in the next case clause". It has at least one solid use-case, which
is demonstrated in this example
<https://gist.github.com/stevestreza/2557dc5ec9e7c694d7ea>

Swift Evolution discussed removing fallthrough on-list in early December
<https://lists.swift.org/pipermail/swift-evolution/2015-December/000226.html> We
came to the consensus that fallthroughoffers sufficient utility to retain
the feature in the language:

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#the-problem-with-fallthrough>The
Problem with Fallthrough.

In Swift, fallthrough does not mean: "execute this case and then continue
pattern matching", which is what many naive users expect. Given the
following code where x is 5, they anticipate the function to print "5"
and then "anything else". This is wrong. Swift prints "5" and then "6".

func test(x : Int) {
    switch x {
    case 5:
        print("5")
        fallthrough
    case 6:
        print("6")
    default:
        print("anything else")
    }
}

Fallthrough is better suited for situations like the following:

case simple where even more subconditions hold: ... do complex things ...; fallthrough
case simple where subconditions hold: ... do other things ...; fallthrough
case simple: ... do base things ...

This example produces a sieve where the most restrictive conditions
execute specialized code and then execute code for less restrictive
conditions.

Fallthrough *cannot* be used for situations like the following example:

case specialized situation 1: ... code specific to situation 1 ...; fallthrough
case specialized situation 2: ... code specific to situation 2 ...; fallthrough
case specialized situation 3: ... code specific to situation 3 ...; fallthrough
case general: ... general code applicable as well to the three specialized situations ...

Those coming from C-like languages might have the insight to expect
(wrongly, it should be noted) "5", then "6", then "anything else", which is
what you'd get with the following flawed C-ish code, where case statements
are missing break.

int x = 5;
switch (x) {
    case 5: NSLog(@"5"); // no break;
    case 6: NSLog(@"6"); // no break;
    default: NSLog(@"anything else");
}

Swift-style switch statements are more powerful and general than C-style
switch statements. While I do not endorse C-style switch statements, I do
think there's a case to be made for continue, which would mean "continue
pattern matching". It would look like this:

case specialized situation 1: ... code specific to situation 1 ...; continue
case specialized situation 2: ... code specific to situation 2 ...; continue
case specialized situation 3: ... code specific to situation 3 ...; continue
case general: ... general code applicable as well to the three specialized situations ...

In this example, code that matched general might execute any of the three
specialized subconditions as well but would not have to fall through each
case. So if a pattern matched scenarios 1 and 3, it would execute those
cases and the general case, but not scenario 2.

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#the-advantages-of-continue>The
advantages of continue

   - If adopted, continue allows code to execute multiple matching
   patterns
   - It naturally reduces code redundancy where fallthrough cannot be
   used but code applies to multiple cases (such as the 1, 3, and general
   example above).
   - It uses an existing control flow transfer keyword, using it in a
   reasonably harmonious application that isn't that far out of step with how
   the keyword is used in other parts of the language.

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#detailed-design>Detailed
Design

In the current design, switch statements support subset of control flow
transfer:

control-transfer-statement ‚Üí break-statement
control-transfer-statement ‚Üí fallthrough-statement
control-transfer-statement ‚Üí return-statement
control-transfer-statement ‚Üí throw-statement

Notably missing is "continue", which this proposal would adopt.

control-transfer-statement ‚Üí continue-statement

The definition of continue in a switch statement would mean "after
executing the previous statements in this case clause, continue pattern
matching the remaining cases until a match or default is found.

continue could either be disallowed in the final case (typically default)
or could be ignored if included.

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#impact-on-existing-code>Impact
on Existing Code

None.

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#alternatives-considered>Alternatives
Considered
Not adopting this idea
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(John McCall) #14

As for all of the other additive changes, I would strongly prefer you to *wait* on even proposing or discussing these things until after the Swift 3.0 evolution cycle is done. Not only is it distracting for the community, but the core team and many others won’t be be able to even read the thread or the responses, thus your discussion cycle will be lacking key input.

On this topic, we specifically discussed this when labeled breaks were being designed, and when they were expanded to ‚Äúdo‚ÄĚ in Swift 2. We specifically decided to allow break but not continue, because we didn‚Äôt want these control flow statements to be ‚Äúanother way to spell a loop‚ÄĚ.

Right. If you're interested in pursuing something like this, you might pitch a proposal that adds a "reswitch" that takes an operand to re-dispatch on; but like Chris says, you should wait until the Swift 4 cycle starts.

John.

···

On Jul 11, 2016, at 3:49 PM, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:

-Chris

On Jul 10, 2016, at 7:27 PM, Erica Sadun via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

A quick pitch to introduce `continue` to switch statements. This would be additive and could not be considered for Swift 3.

-- E

Pitch: Introduce continue to Switch Statements

<https://gist.github.com/erica/04835de3d3d9121ef7308dd9b093158a#introduction>Introduction

This pitch completes the switch statement's control flow transfer suite by introducing continue. Doing so provides functionality that a large portion of newer developers expect from (but do not get from) fallthrough.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Erica Sadun) #15

So I can take it as a given that this is out of scope for Swift 3 too?

https://gist.github.com/erica/a78045d09fa5bb20e6e566295140c84d

-- E

···

On Jul 11, 2016, at 4:49 PM, Chris Lattner <clattner@apple.com> wrote:

As for all of the other additive changes, I would strongly prefer you to *wait* on even proposing or discussing these things until after the Swift 3.0 evolution cycle is done. Not only is it distracting for the community, but the core team and many others won’t be be able to even read the thread or the responses, thus your discussion cycle will be lacking key input.

On this topic, we specifically discussed this when labeled breaks were being designed, and when they were expanded to ‚Äúdo‚ÄĚ in Swift 2. We specifically decided to allow break but not continue, because we didn‚Äôt want these control flow statements to be ‚Äúanother way to spell a loop‚ÄĚ.

-Chris


(Xiaodi Wu) #16

>
> This is a neat idea, and I think a very sensible way to extend the
language. I worry only a little about the following:
>
> Currently, unless preceded immediately by the keyword `fallthrough`, a
condition implicitly excludes all previous conditions. That is, if I write
`switch .. { case a: ...; case b: ...; case c: ... }`, my condition `c` is
really `!a && !b && c`. With more flexible control flow within a switch
statement, reasoning about what cases are matched by any particular
condition after the first becomes increasingly difficult.

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.

I understand. What I'm saying is that control flow becomes more difficult
to reason through in a scenario as follows, which is not possible currently:

Given patterns A, B, C, and D, suppose a value x matches A, C, and D,
whereas another value y matches B and D, and a third value matches B and
C. When evaluating x, y, or z, which statements are executed in the
following switch statement? How many of these reach the default case? What
happens if I append `fallthrough` at the end of case D? What happens if I
move case B after case D? (Yes, I know it is possible to figure it out [my
understanding of the answer to the first question is appended below], but I
hope you'll agree with me that this is much more difficult to decipher than
any switch statement that's currently possible.)

switch x /* or y, or z */ {
case A:
  // ...
  continue
case B:
  // ...
  if C ~= x /* or y, or z, whichever is switched over */ {
    continue
  }
  fallthrough
case C:
  // ...
  if B ~= x /* or y, or z, whichever is switched over */ {
    continue
  }
case D:
  // ...
default:
  // ...
}

[For switch x: statements in cases A and C only, not the default; for
switch y: statements in case B, C and D, not the default; for switch z:
statements in cases B and C, and in the default]

Finally, a really neat thing about `continue` in Swift is the ability to
use labels; would you propose allowing that here? If so, could I label
individual cases and have pattern matching resume at that case? How about
resuming at a previous case? It'd be neat. It'd also make it possible to
make an infinite loop out of a switch statement...

-- E

···

On Sun, Jul 10, 2016 at 10:48 PM, Erica Sadun <erica@ericasadun.com> wrote:

> On Jul 10, 2016, at 8:37 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:


(Erica Sadun) #17

The standard question asks you to print the value and then fizz and/or buzz on the same line and then move to the next line.

If you use the rules you stated ("Any number not a multiple of 3 or 5 will say its value."), it would look like this:

switch value
{
case _ where !(x % 5 == 0 || x % 3 == 0):
    print(value)
case x where x % 3 == 0:
    print("fizz", terminator: "")
    continue
case x where x % 5 == 0:
    print("buzz", terminator: "")
    continue
default:
    print("")
    break
}

If you use the standard rules, it looks like this:

switch value
{
case _:
    print(value, terminator: "")
case x where x % 3 == 0:
    print(" fizz", terminator: "")
    continue
case x where x % 5 == 0:
    print(" buzz", terminator: "")
    continue
default:
    print("")
    break
}

-- E

···

On Jul 11, 2016, at 4:49 AM, Ross O'Brien <narrativium+swift@gmail.com> wrote:

I'm in favour of this concept being available in Swift, but it does need to make a clear distinction somewhere between a case which matches anything (and can catch any fallthrough/continue) and a case which matches none of the above. I don't know whether we need to introduce an explicit term for this, or whether we make this the distinction between 'case _:' and 'default:' (with the side-effect that we can now justify 'default' in the language).

For example: let's use this switch to play fizzbuzz.

switch value
{
  case x where x % 3 == 0:
    print("fizz")
    continue
  case x where x % 5 == 0:
    print("buzz")
  default:
    print(value)
}

I know this is a trivial example, but it's also a frequent example used to teach switch to programmers.
The keywords in play are 'continue' and 'default'. A multiple of 5 but not 3 will print 'buzz' and be done. A multiple of 3 and 5 will print 'fizz buzz'. Any number not a multiple of 3 or 5 will say its value. Crucially, a multiple of 3 but not 5 will say fizz, won't say buzz, and won't say the number itself - whereas if we used 'case _', it would say fizz and then the number itself.


(Leonardo Pessoa) #18

I'll have to give this a -1. Code seems to be confusing with this new
use of continue and we may easily lose control of the flow. If we are
to allow another case to be executed, we should be able to explicitly
direct the flow to the case we want. C# does that using the goto
keyword (yes, I know). I would support this (goto) here but it however
was designed to work well with constant cases and I don't see how this
could work with cases with where expressions like the ones in this
example.

L

···

On 11 July 2016 at 11:54, Erica Sadun via swift-evolution <swift-evolution@swift.org> wrote:

On Jul 11, 2016, at 4:49 AM, Ross O'Brien <narrativium+swift@gmail.com> > wrote:

I'm in favour of this concept being available in Swift, but it does need to
make a clear distinction somewhere between a case which matches anything
(and can catch any fallthrough/continue) and a case which matches none of
the above. I don't know whether we need to introduce an explicit term for
this, or whether we make this the distinction between 'case _:' and
'default:' (with the side-effect that we can now justify 'default' in the
language).

For example: let's use this switch to play fizzbuzz.

switch value
{
  case x where x % 3 == 0:
    print("fizz")
    continue
  case x where x % 5 == 0:
    print("buzz")
  default:
    print(value)
}

I know this is a trivial example, but it's also a frequent example used to
teach switch to programmers.
The keywords in play are 'continue' and 'default'. A multiple of 5 but not 3
will print 'buzz' and be done. A multiple of 3 and 5 will print 'fizz buzz'.
Any number not a multiple of 3 or 5 will say its value. Crucially, a
multiple of 3 but not 5 will say fizz, won't say buzz, and won't say the
number itself - whereas if we used 'case _', it would say fizz and then the
number itself.

The standard question asks you to print the value and then fizz and/or buzz
on the same line and then move to the next line.

If you use the rules you stated ("Any number not a multiple of 3 or 5 will
say its value."), it would look like this:

switch value
{
case _ where !(x % 5 == 0 || x % 3 == 0):
    print(value)
case x where x % 3 == 0:
    print("fizz", terminator: "")
    continue
case x where x % 5 == 0:
    print("buzz", terminator: "")
    continue
default:
    print("")
    break
}

If you use the standard rules, it looks like this:

switch value
{
case _:
    print(value, terminator: "")
case x where x % 3 == 0:
    print(" fizz", terminator: "")
    continue
case x where x % 5 == 0:
    print(" buzz", terminator: "")
    continue
default:
    print("")
    break
}

-- E

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Douglas Gregor) #19

No, *that* is out of scope for *Swift*.

  - Doug

···

On Jul 12, 2016, at 8:47 AM, Erica Sadun via swift-evolution <swift-evolution@swift.org> wrote:

On Jul 11, 2016, at 4:49 PM, Chris Lattner <clattner@apple.com <mailto:clattner@apple.com>> wrote:

As for all of the other additive changes, I would strongly prefer you to *wait* on even proposing or discussing these things until after the Swift 3.0 evolution cycle is done. Not only is it distracting for the community, but the core team and many others won’t be be able to even read the thread or the responses, thus your discussion cycle will be lacking key input.

On this topic, we specifically discussed this when labeled breaks were being designed, and when they were expanded to ‚Äúdo‚ÄĚ in Swift 2. We specifically decided to allow break but not continue, because we didn‚Äôt want these control flow statements to be ‚Äúanother way to spell a loop‚ÄĚ.

-Chris

So I can take it as a given that this is out of scope for Swift 3 too?

https://gist.github.com/erica/a78045d09fa5bb20e6e566295140c84d


(Daniel Steinberg) #20

Love that!

···

On Jul 12, 2016, at 11:47 AM, Erica Sadun via swift-evolution <swift-evolution@swift.org> wrote:

On Jul 11, 2016, at 4:49 PM, Chris Lattner <clattner@apple.com <mailto:clattner@apple.com>> wrote:

As for all of the other additive changes, I would strongly prefer you to *wait* on even proposing or discussing these things until after the Swift 3.0 evolution cycle is done. Not only is it distracting for the community, but the core team and many others won’t be be able to even read the thread or the responses, thus your discussion cycle will be lacking key input.

On this topic, we specifically discussed this when labeled breaks were being designed, and when they were expanded to ‚Äúdo‚ÄĚ in Swift 2. We specifically decided to allow break but not continue, because we didn‚Äôt want these control flow statements to be ‚Äúanother way to spell a loop‚ÄĚ.

-Chris

So I can take it as a given that this is out of scope for Swift 3 too?

https://gist.github.com/erica/a78045d09fa5bb20e6e566295140c84d

-- E

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution