Proposal: Remove the "fallthrough" keyword

In the spirit of some other proposals that remove C or C++ style artifacts, what do folks think about the possibility of removing the "fallthrough" keyword from the language?

My understanding is this keyword is only used for the archaic seeming purpose of perpetuating C-style fallthrough from one switch statement to the subsequent one. The documentation hedges the use of this keyword in forbidding terms that make it clear its use is not encouraged. The presence of the keyword, while an improvement over C’s implicit fallthrough, is a mark of inelegance on an otherwise well-designed, opinionated implementation of swtich statements.

The ugliness of fallthrough’s C-style behavior even demands a caveat in the documentation:

"The fallthrough keyword does not check the case conditions for the switch case that it causes execution to fall into. The fallthrough keyword simply causes code execution to move directly to the statements inside the next case (or default case) block, as in C’s standard switch statement behavior."

To my mind, the caveat explains just what is wrong with fallthrough, both in C or Swift: coded that is clearly labeled with deliberate conditions can nonetheless be reached.

I quipped about this on Twitter, and the most common pushback I got seemed to be from people who either did not know about Swift’s support for comma-separated case statements, or harbored an aesthetic preference for clustering such cases together with fallthrough statements.

In my opinion, unless somebody can think of a strong defense for supporting intentional fallthrough in Swift, removing the keyword would be a move in the direction of minimizing the language’s complexity while also discouraging poor coding style in switch statements.

Thoughts?

Daniel

Streza’s source code is an example of Duff’s Device, which is a big place where switch fallthrough is arguably the cleanest way to do things and the reason why I’d personally prefer to keep it as part of the language.

···

On Dec 4, 2015, at 2:12 PM, Erica Sadun <erica@ericasadun.com> wrote:

Oh let it die, let it die. Any time I use fallthrough I find myself re-factoring to stop using it.

True fact: On all of gist.github.com <http://gist.github.com/&gt;, there are only 22 gist results for "fallthrough language:swift".
Half of those are people just testing out the feature. Most of the remaining ones are just complex cases:
case .Enum1, .Enum2:
expressed as
case .Enum1: fallthrough
case .Enum2:

And then there's streza: Base32.swift · GitHub I'm pretty sure that ponies were harmed in the production of whatever that last bit is.

On Dec 4, 2015, at 3:05 PM, jalkut@red-sweater.com <mailto:jalkut@red-sweater.com> wrote:

In the spirit of some other proposals that remove C or C++ style artifacts, what do folks think about the possibility of removing the "fallthrough" keyword from the language?

My understanding is this keyword is only used for the archaic seeming purpose of perpetuating C-style fallthrough from one switch statement to the subsequent one. The documentation hedges the use of this keyword in forbidding terms that make it clear its use is not encouraged. The presence of the keyword, while an improvement over C’s implicit fallthrough, is a mark of inelegance on an otherwise well-designed, opinionated implementation of swtich statements.

The ugliness of fallthrough’s C-style behavior even demands a caveat in the documentation:

"The fallthrough keyword does not check the case conditions for the switch case that it causes execution to fall into. The fallthrough keyword simply causes code execution to move directly to the statements inside the next case (or default case) block, as in C’s standard switch statement behavior."

To my mind, the caveat explains just what is wrong with fallthrough, both in C or Swift: coded that is clearly labeled with deliberate conditions can nonetheless be reached.

I quipped about this on Twitter, and the most common pushback I got seemed to be from people who either did not know about Swift’s support for comma-separated case statements, or harbored an aesthetic preference for clustering such cases together with fallthrough statements.

In my opinion, unless somebody can think of a strong defense for supporting intentional fallthrough in Swift, removing the keyword would be a move in the direction of minimizing the language’s complexity while also discouraging poor coding style in switch statements.

Thoughts?

Daniel

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto: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

I don't use `fallthrough` very often, but when I do, it's extremely
useful. Removing it would make some of my code significantly harder to
read. In fact, I actually wish `fallthrough` was more powerful, allowing
me to fall into cases that bound identifiers if every bound identifier
was already bound with the same type in the current case, though I
understand why the language doesn't allow it (it's significant
complexity for a relatively minor gain).

Similarly, the ability to use `break` in switch statements, while not
something I use very often outside of using it for empty cases, is still
invaluable when I do occasionally need it. And since you can already
break out of loops by using a label, I don't see why we should remove
it. An example of doing that is

loop: for thing in collection {
    switch thing {
    case .Special: break loop
    default: ...
    }
}

-Kevin Ballard

···

On Fri, Dec 4, 2015, at 02:14 PM, Sean Heber wrote:

I’ve always shied away from fallthrough no matter what language I’m
using. Perhaps there are situations where it is required, but in spirit I
agree it maybe should be removed.

I’d amend this to also prevent “break” from applying to switch statements
so that they can break out of loops if you’ve nested a switch inside of a
loop. I ran into this situation and spent entirely too long confused
about why it didn’t break out like I thought it should have:

for thing in collection {
  switch thing {
  case .Special: break
  default { … }
  }
}

The reason I expected this to work is that I don’t need to use a “break”
in Swift cases so it stood to reason this would mean the “break”
statement would only apply to the loop. I was wrong. :P

l8r
Sean

> On Dec 4, 2015, at 4:05 PM, jalkut@red-sweater.com wrote:
>
> In the spirit of some other proposals that remove C or C++ style artifacts, what do folks think about the possibility of removing the "fallthrough" keyword from the language?
>
> My understanding is this keyword is only used for the archaic seeming purpose of perpetuating C-style fallthrough from one switch statement to the subsequent one. The documentation hedges the use of this keyword in forbidding terms that make it clear its use is not encouraged. The presence of the keyword, while an improvement over C’s implicit fallthrough, is a mark of inelegance on an otherwise well-designed, opinionated implementation of swtich statements.
>
> The ugliness of fallthrough’s C-style behavior even demands a caveat in the documentation:
>
> "The fallthrough keyword does not check the case conditions for the switch case that it causes execution to fall into. The fallthrough keyword simply causes code execution to move directly to the statements inside the next case (or default case) block, as in C’s standard switch statement behavior."
>
> To my mind, the caveat explains just what is wrong with fallthrough, both in C or Swift: coded that is clearly labeled with deliberate conditions can nonetheless be reached.
>
> I quipped about this on Twitter, and the most common pushback I got seemed to be from people who either did not know about Swift’s support for comma-separated case statements, or harbored an aesthetic preference for clustering such cases together with fallthrough statements.
>
> In my opinion, unless somebody can think of a strong defense for supporting intentional fallthrough in Swift, removing the keyword would be a move in the direction of minimizing the language’s complexity while also discouraging poor coding style in switch statements.
>
> Thoughts?
>
> Daniel
>
> _______________________________________________
> 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

Yes. You beat me to it but I agree. I think having fallthrough could be an important performance optimization as refactoring would either result in the overhead of a function call or replicated code. I would also prefer to keep it in the toolbox.

Ray Fix

···

On Dec 4, 2015, at 2:16 PM, Greg Titus <greg@omnigroup.com> wrote:

Streza’s source code is an example of Duff’s Device, which is a big place where switch fallthrough is arguably the cleanest way to do things and the reason why I’d personally prefer to keep it as part of the language.

I should have mentioned that 99% of the time the overhead of a function call doesn’t matter, but when it does… it is great to have.

Ray Fix

···

On Dec 4, 2015, at 2:20 PM, Ray Fix <rayfix@gmail.com> wrote:

On Dec 4, 2015, at 2:16 PM, Greg Titus <greg@omnigroup.com <mailto:greg@omnigroup.com>> wrote:

Streza’s source code is an example of Duff’s Device, which is a big place where switch fallthrough is arguably the cleanest way to do things and the reason why I’d personally prefer to keep it as part of the language.

Yes. You beat me to it but I agree. I think having fallthrough could be an important performance optimization as refactoring would either result in the overhead of a function call or replicated code. I would also prefer to keep it in the toolbox.

It's not actually Duff's Device. Duff's Device relies on the fact that
C switch statements don't actually introduce a new scope, and so it
overlaps a switch with a do-while loop. This lets it only test the
number of bytes once, to jump into the middle of the loop, and then it
switches over to a while loop that decrements a counter every 8
instructions. Basically, it's a trick for manual loop unrolling that
deals with non-multiple-of-8 counts efficiently.

Steve's code is also an example of manual loop unrolling that deals with
non-multiple-of-8 counts, but it has calculate the number of bytes on
every iteration instead of once. It's a good example of one of the uses
of `fallthrough`, it's just not Duff's Device. It's impossible to use
Duff's Device in Swift.

-Kevin Ballard

···

On Fri, Dec 4, 2015, at 02:16 PM, Greg Titus wrote:

Streza’s source code is an example of Duff’s Device, which is a big
place where switch fallthrough is arguably the cleanest way to do
things and the reason why I’d personally prefer to keep it as part of
the language.

On Dec 4, 2015, at 2:12 PM, Erica Sadun <erica@ericasadun.com> wrote:

Oh let it die, let it die. Any time I use fallthrough I find myself
re-factoring to stop using it.

*True fact*: On all of gist.github.com[1], there are only 22 gist
results for "fallthrough language:swift". Half of those are people
just testing out the feature. Most of the remaining ones are just
complex cases: *case .Enum1, .Enum2:* expressed as *case .Enum1:
fallthrough* *case .Enum2:*

And then there's streza:
Base32.swift · GitHub I'm pretty
sure that ponies were harmed in the production of whatever that last
bit is.

On Dec 4, 2015, at 3:05 PM, jalkut@red-sweater.com wrote:

In the spirit of some other proposals that remove C or C++ style
artifacts, what do folks think about the possibility of removing the
"fallthrough" keyword from the language?

My understanding is this keyword is only used for the archaic
seeming purpose of perpetuating C-style fallthrough from one switch
statement to the subsequent one. The documentation hedges the use of
this keyword in forbidding terms that make it clear its use is not
encouraged. The presence of the keyword, while an improvement over
C’s implicit fallthrough, is a mark of inelegance on an otherwise
well-designed, opinionated implementation of swtich statements.

The ugliness of fallthrough’s C-style behavior even demands a caveat
in the documentation:

"The fallthrough keyword does not check the case conditions for the
switch case that it causes execution to fall into. The fallthrough
keyword simply causes code execution to move directly to the
statements inside the next case (or default case) block, as in C’s
standard switch statement behavior."

To my mind, the caveat explains just what is wrong with fallthrough,
both in C or Swift: coded that is clearly labeled with deliberate
conditions can nonetheless be reached.

I quipped about this on Twitter, and the most common pushback I got
seemed to be from people who either did not know about Swift’s
support for comma-separated case statements, or harbored an
aesthetic preference for clustering such cases together with
fallthrough statements.

In my opinion, unless somebody can think of a strong defense for
supporting intentional fallthrough in Swift, removing the keyword
would be a move in the direction of minimizing the language’s
complexity while also discouraging poor coding style in switch
statements.

Thoughts?

Daniel

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

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

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

Links:

  1. http://gist.github.com/

It's not actually Duff's Device. Duff's Device relies on the fact that C switch statements don't actually introduce a new scope, and so it overlaps a switch with a do-while loop. This lets it only test the number of bytes once, to jump into the middle of the loop, and then it switches over to a while loop that decrements a counter every 8 instructions. Basically, it's a trick for manual loop unrolling that deals with non-multiple-of-8 counts efficiently.

To be pedantic, C switch statements do introduce a new scope. What Duff’s Device exploits is that switch is allowed to jump into (almost) arbitrary scopes, and cases can appear anywhere recursively inside a switch.

But your point that Swift’s switch requires cases to be at the top level within a switch and thus prevents the use of Duff’s Device is 100% correct.

John.

···

On Dec 4, 2015, at 2:33 PM, Kevin Ballard <kevin@sb.org> wrote:

Steve's code is also an example of manual loop unrolling that deals with non-multiple-of-8 counts, but it has calculate the number of bytes on every iteration instead of once. It's a good example of one of the uses of `fallthrough`, it's just not Duff's Device. It's impossible to use Duff's Device in Swift.

-Kevin Ballard

On Fri, Dec 4, 2015, at 02:16 PM, Greg Titus wrote:

Streza’s source code is an example of Duff’s Device, which is a big place where switch fallthrough is arguably the cleanest way to do things and the reason why I’d personally prefer to keep it as part of the language.

On Dec 4, 2015, at 2:12 PM, Erica Sadun <erica@ericasadun.com <mailto:erica@ericasadun.com>> wrote:

Oh let it die, let it die. Any time I use fallthrough I find myself re-factoring to stop using it.

True fact: On all of gist.github.com <http://gist.github.com/&gt;, there are only 22 gist results for "fallthrough language:swift".
Half of those are people just testing out the feature. Most of the remaining ones are just complex cases:
case .Enum1, .Enum2:
expressed as
case .Enum1: fallthrough
case .Enum2:

And then there's streza: Base32.swift · GitHub I'm pretty sure that ponies were harmed in the production of whatever that last bit is.

On Dec 4, 2015, at 3:05 PM, jalkut@red-sweater.com <mailto:jalkut@red-sweater.com> wrote:

In the spirit of some other proposals that remove C or C++ style artifacts, what do folks think about the possibility of removing the "fallthrough" keyword from the language?

My understanding is this keyword is only used for the archaic seeming purpose of perpetuating C-style fallthrough from one switch statement to the subsequent one. The documentation hedges the use of this keyword in forbidding terms that make it clear its use is not encouraged. The presence of the keyword, while an improvement over C’s implicit fallthrough, is a mark of inelegance on an otherwise well-designed, opinionated implementation of swtich statements.

The ugliness of fallthrough’s C-style behavior even demands a caveat in the documentation:

"The fallthrough keyword does not check the case conditions for the switch case that it causes execution to fall into. The fallthrough keyword simply causes code execution to move directly to the statements inside the next case (or default case) block, as in C’s standard switch statement behavior."

To my mind, the caveat explains just what is wrong with fallthrough, both in C or Swift: coded that is clearly labeled with deliberate conditions can nonetheless be reached.

I quipped about this on Twitter, and the most common pushback I got seemed to be from people who either did not know about Swift’s support for comma-separated case statements, or harbored an aesthetic preference for clustering such cases together with fallthrough statements.

In my opinion, unless somebody can think of a strong defense for supporting intentional fallthrough in Swift, removing the keyword would be a move in the direction of minimizing the language’s complexity while also discouraging poor coding style in switch statements.

Thoughts?

Daniel

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

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

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto: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

Oh you're right, what I meant to say was that case statements don't
introduce a new scope. The do-while loop is contained entirely within
the scope of the switch itself, and the case statements act like goto
labels so it can jump into the scope of the do-while.

-Kevin Ballard

···

On Fri, Dec 4, 2015, at 02:42 PM, John McCall wrote:

On Dec 4, 2015, at 2:33 PM, Kevin Ballard <kevin@sb.org> wrote: It's
not actually Duff's Device. Duff's Device relies on the fact that C
switch statements don't actually introduce a new scope, and so it
overlaps a switch with a do-while loop. This lets it only test the
number of bytes once, to jump into the middle of the loop, and then
it switches over to a while loop that decrements a counter every 8
instructions. Basically, it's a trick for manual loop unrolling that
deals with non-multiple-of-8 counts efficiently.

To be pedantic, C switch statements do introduce a new scope. What
Duff’s Device exploits is that switch is allowed to jump into
(almost) arbitrary scopes, and cases can appear anywhere recursively
inside a switch.

Oh let it die, let it die. Any time I use fallthrough I find myself re-factoring to stop using it.

True fact: On all of gist.github.com, there are only 22 gist results for "fallthrough language:swift".
Half of those are people just testing out the feature. Most of the remaining ones are just complex cases:
case .Enum1, .Enum2:
expressed as
case .Enum1: fallthrough
case .Enum2:

And then there's streza: Base32.swift · GitHub I'm pretty sure that ponies were harmed in the production of whatever that last bit is.

···

On Dec 4, 2015, at 3:05 PM, jalkut@red-sweater.com wrote:

In the spirit of some other proposals that remove C or C++ style artifacts, what do folks think about the possibility of removing the "fallthrough" keyword from the language?

My understanding is this keyword is only used for the archaic seeming purpose of perpetuating C-style fallthrough from one switch statement to the subsequent one. The documentation hedges the use of this keyword in forbidding terms that make it clear its use is not encouraged. The presence of the keyword, while an improvement over C’s implicit fallthrough, is a mark of inelegance on an otherwise well-designed, opinionated implementation of swtich statements.

The ugliness of fallthrough’s C-style behavior even demands a caveat in the documentation:

"The fallthrough keyword does not check the case conditions for the switch case that it causes execution to fall into. The fallthrough keyword simply causes code execution to move directly to the statements inside the next case (or default case) block, as in C’s standard switch statement behavior."

To my mind, the caveat explains just what is wrong with fallthrough, both in C or Swift: coded that is clearly labeled with deliberate conditions can nonetheless be reached.

I quipped about this on Twitter, and the most common pushback I got seemed to be from people who either did not know about Swift’s support for comma-separated case statements, or harbored an aesthetic preference for clustering such cases together with fallthrough statements.

In my opinion, unless somebody can think of a strong defense for supporting intentional fallthrough in Swift, removing the keyword would be a move in the direction of minimizing the language’s complexity while also discouraging poor coding style in switch statements.

Thoughts?

Daniel

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

On a few occasions, fallthrough has been the most expressive path for a non-performance-related reason: rather, because it’s not possible to destructure a value and also have multiple predicates in a case, e.g.

switch downloadStatus {
  case let .Downloading(progress) where progress == 0.0:
    fallthrough
  case .NotStarted:
    // do things implying we have no data
  default:
    // do things implying we have some data
}

Of course, we might resolve this by changing the destructuring semantics.

···

On Dec 4, 2015, at 2:05 PM, jalkut@red-sweater.com wrote:

In the spirit of some other proposals that remove C or C++ style artifacts, what do folks think about the possibility of removing the "fallthrough" keyword from the language?

My understanding is this keyword is only used for the archaic seeming purpose of perpetuating C-style fallthrough from one switch statement to the subsequent one. The documentation hedges the use of this keyword in forbidding terms that make it clear its use is not encouraged. The presence of the keyword, while an improvement over C’s implicit fallthrough, is a mark of inelegance on an otherwise well-designed, opinionated implementation of swtich statements.

The ugliness of fallthrough’s C-style behavior even demands a caveat in the documentation:

"The fallthrough keyword does not check the case conditions for the switch case that it causes execution to fall into. The fallthrough keyword simply causes code execution to move directly to the statements inside the next case (or default case) block, as in C’s standard switch statement behavior."

To my mind, the caveat explains just what is wrong with fallthrough, both in C or Swift: coded that is clearly labeled with deliberate conditions can nonetheless be reached.

I quipped about this on Twitter, and the most common pushback I got seemed to be from people who either did not know about Swift’s support for comma-separated case statements, or harbored an aesthetic preference for clustering such cases together with fallthrough statements.

In my opinion, unless somebody can think of a strong defense for supporting intentional fallthrough in Swift, removing the keyword would be a move in the direction of minimizing the language’s complexity while also discouraging poor coding style in switch statements.

Thoughts?

Daniel

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

I courteously remove my objections.

-- E

···

On Dec 4, 2015, at 3:25 PM, Ray Fix <rayfix@gmail.com> wrote:

On Dec 4, 2015, at 2:20 PM, Ray Fix <rayfix@gmail.com <mailto:rayfix@gmail.com>> wrote:

On Dec 4, 2015, at 2:16 PM, Greg Titus <greg@omnigroup.com <mailto:greg@omnigroup.com>> wrote:

Streza’s source code is an example of Duff’s Device, which is a big place where switch fallthrough is arguably the cleanest way to do things and the reason why I’d personally prefer to keep it as part of the language.

Yes. You beat me to it but I agree. I think having fallthrough could be an important performance optimization as refactoring would either result in the overhead of a function call or replicated code. I would also prefer to keep it in the toolbox.

I should have mentioned that 99% of the time the overhead of a function call doesn’t matter, but when it does… it is great to have.

Ray Fix

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

I’ve always shied away from fallthrough no matter what language I’m using. Perhaps there are situations where it is required, but in spirit I agree it maybe should be removed.

I’d amend this to also prevent “break” from applying to switch statements so that they can break out of loops if you’ve nested a switch inside of a loop. I ran into this situation and spent entirely too long confused about why it didn’t break out like I thought it should have:

for thing in collection {
  switch thing {
  case .Special: break
  default { … }
  }
}

The reason I expected this to work is that I don’t need to use a “break” in Swift cases so it stood to reason this would mean the “break” statement would only apply to the loop. I was wrong. :P

l8r
Sean

···

On Dec 4, 2015, at 4:05 PM, jalkut@red-sweater.com wrote:

In the spirit of some other proposals that remove C or C++ style artifacts, what do folks think about the possibility of removing the "fallthrough" keyword from the language?

My understanding is this keyword is only used for the archaic seeming purpose of perpetuating C-style fallthrough from one switch statement to the subsequent one. The documentation hedges the use of this keyword in forbidding terms that make it clear its use is not encouraged. The presence of the keyword, while an improvement over C’s implicit fallthrough, is a mark of inelegance on an otherwise well-designed, opinionated implementation of swtich statements.

The ugliness of fallthrough’s C-style behavior even demands a caveat in the documentation:

"The fallthrough keyword does not check the case conditions for the switch case that it causes execution to fall into. The fallthrough keyword simply causes code execution to move directly to the statements inside the next case (or default case) block, as in C’s standard switch statement behavior."

To my mind, the caveat explains just what is wrong with fallthrough, both in C or Swift: coded that is clearly labeled with deliberate conditions can nonetheless be reached.

I quipped about this on Twitter, and the most common pushback I got seemed to be from people who either did not know about Swift’s support for comma-separated case statements, or harbored an aesthetic preference for clustering such cases together with fallthrough statements.

In my opinion, unless somebody can think of a strong defense for supporting intentional fallthrough in Swift, removing the keyword would be a move in the direction of minimizing the language’s complexity while also discouraging poor coding style in switch statements.

Thoughts?

Daniel

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

`fallthrough` is conceptually similar to `goto` in that both allow natural expression of concepts that exist at the instruction level but are otherwise difficult to express with nested control structures. `fallthrough` is perhaps slightly less objectionable because control flow remains local, but it has a similar role.

It is not particularly natural to write `switch` statements with `fallthrough` in the reverse order that can be seen in Duff’s Device and similar constructs (case 7 falls through to 6 which falls through to 5, etc.). It’s just because you know for certain that all the code in case 6 would be duplicated in case 7, so 7 can transfer into 6 without a jump instruction. Communicating that to the compiler without `fallthrough` requires deeply nested `if`s.

One defense comes to mind: there is talk of Swift aiming at systems programming. Is writing a threaded interpreter loop within the potential scope of Swift? That’s a use case that could make use of both `fallthrough` and `goto` (computed goto, really).

switch op {
case LOAD_INDIRECT:
   in0 = memory[in1]
   fallthrough
case LOAD:
   out0 = memory[in0]
//...
}

I am personally interested in the prospect of a language that can scale up to high-level concepts and down to “portable assembler,” but I don’t know if that is the right direction for Swift’s evolution.

Cheers,
John

···

On Dec 4, 2015, at 2:42 PM, John McCall <rjmccall@apple.com> wrote:

On Dec 4, 2015, at 2:33 PM, Kevin Ballard <kevin@sb.org <mailto:kevin@sb.org>> wrote:
It's not actually Duff's Device. Duff's Device relies on the fact that C switch statements don't actually introduce a new scope, and so it overlaps a switch with a do-while loop. This lets it only test the number of bytes once, to jump into the middle of the loop, and then it switches over to a while loop that decrements a counter every 8 instructions. Basically, it's a trick for manual loop unrolling that deals with non-multiple-of-8 counts efficiently.

To be pedantic, C switch statements do introduce a new scope. What Duff’s Device exploits is that switch is allowed to jump into (almost) arbitrary scopes, and cases can appear anywhere recursively inside a switch.

But your point that Swift’s switch requires cases to be at the top level within a switch and thus prevents the use of Duff’s Device is 100% correct.

John.

Steve's code is also an example of manual loop unrolling that deals with non-multiple-of-8 counts, but it has calculate the number of bytes on every iteration instead of once. It's a good example of one of the uses of `fallthrough`, it's just not Duff's Device. It's impossible to use Duff's Device in Swift.

-Kevin Ballard

On Fri, Dec 4, 2015, at 02:16 PM, Greg Titus wrote:

Streza’s source code is an example of Duff’s Device, which is a big place where switch fallthrough is arguably the cleanest way to do things and the reason why I’d personally prefer to keep it as part of the language.

On Dec 4, 2015, at 2:12 PM, Erica Sadun <erica@ericasadun.com <mailto:erica@ericasadun.com>> wrote:

Oh let it die, let it die. Any time I use fallthrough I find myself re-factoring to stop using it.

True fact: On all of gist.github.com <http://gist.github.com/&gt;, there are only 22 gist results for "fallthrough language:swift".
Half of those are people just testing out the feature. Most of the remaining ones are just complex cases:
case .Enum1, .Enum2:
expressed as
case .Enum1: fallthrough
case .Enum2:

And then there's streza: Base32.swift · GitHub I'm pretty sure that ponies were harmed in the production of whatever that last bit is.

On Dec 4, 2015, at 3:05 PM, jalkut@red-sweater.com <mailto:jalkut@red-sweater.com> wrote:

In the spirit of some other proposals that remove C or C++ style artifacts, what do folks think about the possibility of removing the "fallthrough" keyword from the language?

My understanding is this keyword is only used for the archaic seeming purpose of perpetuating C-style fallthrough from one switch statement to the subsequent one. The documentation hedges the use of this keyword in forbidding terms that make it clear its use is not encouraged. The presence of the keyword, while an improvement over C’s implicit fallthrough, is a mark of inelegance on an otherwise well-designed, opinionated implementation of swtich statements.

The ugliness of fallthrough’s C-style behavior even demands a caveat in the documentation:

"The fallthrough keyword does not check the case conditions for the switch case that it causes execution to fall into. The fallthrough keyword simply causes code execution to move directly to the statements inside the next case (or default case) block, as in C’s standard switch statement behavior."

To my mind, the caveat explains just what is wrong with fallthrough, both in C or Swift: coded that is clearly labeled with deliberate conditions can nonetheless be reached.

I quipped about this on Twitter, and the most common pushback I got seemed to be from people who either did not know about Swift’s support for comma-separated case statements, or harbored an aesthetic preference for clustering such cases together with fallthrough statements.

In my opinion, unless somebody can think of a strong defense for supporting intentional fallthrough in Swift, removing the keyword would be a move in the direction of minimizing the language’s complexity while also discouraging poor coding style in switch statements.

Thoughts?

Daniel

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

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

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

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

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

I’m not making an argument either way, but I want to point something out: there is a major difference between fallthrough vs ++/c-style-for. To someone who doesn’t know them, the later are "syntactic magic” with no reasonable way to decipher other than looking them up somewhere. The former is an English word whose meaning is obvious in context.

All I’m saying is that to a reader of code, the “badness” of ++ and c-style for loops is greater than the “badness" of fallthrough.

-Chris

···

On Dec 4, 2015, at 2:05 PM, jalkut@red-sweater.com wrote:

In the spirit of some other proposals that remove C or C++ style artifacts, what do folks think about the possibility of removing the "fallthrough" keyword from the language?

Given that Swift has the goal to also be a low level language, fallthrough is really useful for conciseness and readability.

in system programming C, I find myself writing things like this very often:

switch (some_value) {
case ENUM_VALUE_REFINED:
    if (validate(some_value)) {
        return NULL;
    }
    /* fallthrough */
case ENUM_VALUE_BASE:
    handle_enum_value();
    …
}

Where the swift equivalent would roughly be:

switch some_value {
case .REFINED:
    if !validate(some_value) { return NULL }
    fallthrough
case .BASE:
    handle_enum_value();
}

This is as readable as it gets and is a pattern that the libdispatch has in several places e.g.

Of course, you cannot fall through to arbitrary cases, so things like this C code cannot be done in swift:

switch (some_value) {
case ENUM_VALUE_REFINED_1:
    if (validate(some_value)) {
        return NULL;
    }
    goto base_value;
case ENUM_VALUE_REFINED_2:
    if (validate(some_value)) {
        return NULL;
    }
    goto base_value;

case ENUM_VALUE_BASE:
base_value:
    handle_enum_value();
    …
}

cannot be written in swift, despite also being quite useful.

Jumping between arbitrary points inside a switch is disgusting. jumping from label to label is useful and not harmful especially in swift where you can’t place code between the “switch” and the first case.

-Pierre

···

On Dec 5, 2015, at 9:02 AM, Chris Lattner <clattner@apple.com> wrote:

On Dec 4, 2015, at 2:05 PM, jalkut@red-sweater.com wrote:

In the spirit of some other proposals that remove C or C++ style artifacts, what do folks think about the possibility of removing the "fallthrough" keyword from the language?

I’m not making an argument either way, but I want to point something out: there is a major difference between fallthrough vs ++/c-style-for. To someone who doesn’t know them, the later are "syntactic magic” with no reasonable way to decipher other than looking them up somewhere. The former is an English word whose meaning is obvious in context.

All I’m saying is that to a reader of code, the “badness” of ++ and c-style for loops is greater than the “badness" of fallthrough.

`fallthrough` is conceptually similar to `goto` in that both allow natural expression of concepts that exist at the instruction level but are otherwise difficult to express with nested control structures. `fallthrough` is perhaps slightly less objectionable because control flow remains local, but it has a similar role.

It is not particularly natural to write `switch` statements with `fallthrough` in the reverse order that can be seen in Duff’s Device and similar constructs (case 7 falls through to 6 which falls through to 5, etc.). It’s just because you know for certain that all the code in case 6 would be duplicated in case 7, so 7 can transfer into 6 without a jump instruction. Communicating that to the compiler without `fallthrough` requires deeply nested `if`s.

Right. One idea that I’ve always had for “fallthrough” is that we might parameterize it in the future; parameterized it would mean “repeat the switch with this new value”, so that unparameterized fallthrough would mean “repeat the switch with a notional value that ends up in the next case”. There’s a very common pattern in switches of deferring to another case that I’ve always found very awkward to write in C, and while sometimes there’s no choice but to extract a helper function, there’s a still-fairly-structural code pattern here that I think we can sensibly support.

On the other hand, there’s an argument that this is an inappropriate extension for “fallthrough” specifically, which is one reason we’ve never pursued it.

John.

···

On Dec 4, 2015, at 11:37 PM, John Calsbeek <john.calsbeek+lists@gmail.com> wrote:

One defense comes to mind: there is talk of Swift aiming at systems programming. Is writing a threaded interpreter loop within the potential scope of Swift? That’s a use case that could make use of both `fallthrough` and `goto` (computed goto, really).

switch op {
case LOAD_INDIRECT:
   in0 = memory[in1]
   fallthrough
case LOAD:
   out0 = memory[in0]
//...
}

I am personally interested in the prospect of a language that can scale up to high-level concepts and down to “portable assembler,” but I don’t know if that is the right direction for Swift’s evolution.

Cheers,
John

On Dec 4, 2015, at 2:42 PM, John McCall <rjmccall@apple.com <mailto:rjmccall@apple.com>> wrote:

On Dec 4, 2015, at 2:33 PM, Kevin Ballard <kevin@sb.org <mailto:kevin@sb.org>> wrote:
It's not actually Duff's Device. Duff's Device relies on the fact that C switch statements don't actually introduce a new scope, and so it overlaps a switch with a do-while loop. This lets it only test the number of bytes once, to jump into the middle of the loop, and then it switches over to a while loop that decrements a counter every 8 instructions. Basically, it's a trick for manual loop unrolling that deals with non-multiple-of-8 counts efficiently.

To be pedantic, C switch statements do introduce a new scope. What Duff’s Device exploits is that switch is allowed to jump into (almost) arbitrary scopes, and cases can appear anywhere recursively inside a switch.

But your point that Swift’s switch requires cases to be at the top level within a switch and thus prevents the use of Duff’s Device is 100% correct.

John.

Steve's code is also an example of manual loop unrolling that deals with non-multiple-of-8 counts, but it has calculate the number of bytes on every iteration instead of once. It's a good example of one of the uses of `fallthrough`, it's just not Duff's Device. It's impossible to use Duff's Device in Swift.

-Kevin Ballard

On Fri, Dec 4, 2015, at 02:16 PM, Greg Titus wrote:

Streza’s source code is an example of Duff’s Device, which is a big place where switch fallthrough is arguably the cleanest way to do things and the reason why I’d personally prefer to keep it as part of the language.

On Dec 4, 2015, at 2:12 PM, Erica Sadun <erica@ericasadun.com <mailto:erica@ericasadun.com>> wrote:

Oh let it die, let it die. Any time I use fallthrough I find myself re-factoring to stop using it.

True fact: On all of gist.github.com <http://gist.github.com/&gt;, there are only 22 gist results for "fallthrough language:swift".
Half of those are people just testing out the feature. Most of the remaining ones are just complex cases:
case .Enum1, .Enum2:
expressed as
case .Enum1: fallthrough
case .Enum2:

And then there's streza: Base32.swift · GitHub I'm pretty sure that ponies were harmed in the production of whatever that last bit is.

On Dec 4, 2015, at 3:05 PM, jalkut@red-sweater.com <mailto:jalkut@red-sweater.com> wrote:

In the spirit of some other proposals that remove C or C++ style artifacts, what do folks think about the possibility of removing the "fallthrough" keyword from the language?

My understanding is this keyword is only used for the archaic seeming purpose of perpetuating C-style fallthrough from one switch statement to the subsequent one. The documentation hedges the use of this keyword in forbidding terms that make it clear its use is not encouraged. The presence of the keyword, while an improvement over C’s implicit fallthrough, is a mark of inelegance on an otherwise well-designed, opinionated implementation of swtich statements.

The ugliness of fallthrough’s C-style behavior even demands a caveat in the documentation:

"The fallthrough keyword does not check the case conditions for the switch case that it causes execution to fall into. The fallthrough keyword simply causes code execution to move directly to the statements inside the next case (or default case) block, as in C’s standard switch statement behavior."

To my mind, the caveat explains just what is wrong with fallthrough, both in C or Swift: coded that is clearly labeled with deliberate conditions can nonetheless be reached.

I quipped about this on Twitter, and the most common pushback I got seemed to be from people who either did not know about Swift’s support for comma-separated case statements, or harbored an aesthetic preference for clustering such cases together with fallthrough statements.

In my opinion, unless somebody can think of a strong defense for supporting intentional fallthrough in Swift, removing the keyword would be a move in the direction of minimizing the language’s complexity while also discouraging poor coding style in switch statements.

Thoughts?

Daniel

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

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

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

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

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto: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

I understand there might be some cases in which the syntax provided is indeed useful for experienced programmers writing their code. However, in almost all the examples here, I had to struggle to understand the logic behind the code. Not because it’s poorly written... probably because this syntax may be used for many different purposes, so it’s hard to get what exactly is the intent behind each use.

In Pierre’s latest example, for instance, it took me a few seconds to understand what was going on. I know it’s a simplified case, but it seems clearer to me to just write something like

if some_value == .Refined && !validate(some_value) {
  return NULL
}
handle_enum_value()

More complex cases make for a better argument for `switch`es, mainly because they avoid big `if` pyramids, but especially in those I feel the resulting code is significantly harder to understand.

···

On Dec 5, 2015, at 12:15 PM, Pierre Habouzit <phabouzit@apple.com> wrote:

On Dec 5, 2015, at 9:02 AM, Chris Lattner <clattner@apple.com <mailto:clattner@apple.com>> wrote:

On Dec 4, 2015, at 2:05 PM, jalkut@red-sweater.com <mailto:jalkut@red-sweater.com> wrote:

In the spirit of some other proposals that remove C or C++ style artifacts, what do folks think about the possibility of removing the "fallthrough" keyword from the language?

I’m not making an argument either way, but I want to point something out: there is a major difference between fallthrough vs ++/c-style-for. To someone who doesn’t know them, the later are "syntactic magic” with no reasonable way to decipher other than looking them up somewhere. The former is an English word whose meaning is obvious in context.

All I’m saying is that to a reader of code, the “badness” of ++ and c-style for loops is greater than the “badness" of fallthrough.

Given that Swift has the goal to also be a low level language, fallthrough is really useful for conciseness and readability.

in system programming C, I find myself writing things like this very often:

switch (some_value) {
case ENUM_VALUE_REFINED:
    if (validate(some_value)) {
        return NULL;
    }
    /* fallthrough */
case ENUM_VALUE_BASE:
    handle_enum_value();
    …
}

Where the swift equivalent would roughly be:

switch some_value {
case .REFINED:
    if !validate(some_value) { return NULL }
    fallthrough
case .BASE:
    handle_enum_value();
}

This is as readable as it gets and is a pattern that the libdispatch has in several places e.g.

Of course, you cannot fall through to arbitrary cases, so things like this C code cannot be done in swift:

switch (some_value) {
case ENUM_VALUE_REFINED_1:
    if (validate(some_value)) {
        return NULL;
    }
    goto base_value;
case ENUM_VALUE_REFINED_2:
    if (validate(some_value)) {
        return NULL;
    }
    goto base_value;

case ENUM_VALUE_BASE:
base_value:
    handle_enum_value();
    …
}

cannot be written in swift, despite also being quite useful.

Jumping between arbitrary points inside a switch is disgusting. jumping from label to label is useful and not harmful especially in swift where you can’t place code between the “switch” and the first case.

-Pierre

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

`fallthrough` is conceptually similar to `goto` in that both allow natural expression of concepts that exist at the instruction level but are otherwise difficult to express with nested control structures. `fallthrough` is perhaps slightly less objectionable because control flow remains local, but it has a similar role.

It is not particularly natural to write `switch` statements with `fallthrough` in the reverse order that can be seen in Duff’s Device and similar constructs (case 7 falls through to 6 which falls through to 5, etc.). It’s just because you know for certain that all the code in case 6 would be duplicated in case 7, so 7 can transfer into 6 without a jump instruction. Communicating that to the compiler without `fallthrough` requires deeply nested `if`s.

Right. One idea that I’ve always had for “fallthrough” is that we might parameterize it in the future; parameterized it would mean “repeat the switch with this new value”, so that unparameterized fallthrough would mean “repeat the switch with a notional value that ends up in the next case”. There’s a very common pattern in switches of deferring to another case that I’ve always found very awkward to write in C, and while sometimes there’s no choice but to extract a helper function, there’s a still-fairly-structural code pattern here that I think we can sensibly support.

On the other hand, there’s an argument that this is an inappropriate extension for “fallthrough” specifically, which is one reason we’ve never pursued it.

Oh, I see that Joe already brought this up, spelled “reswitch”.

John.

···

On Dec 5, 2015, at 1:31 PM, John McCall via swift-evolution <swift-evolution@swift.org> wrote:

On Dec 4, 2015, at 11:37 PM, John Calsbeek <john.calsbeek+lists@gmail.com <mailto:john.calsbeek+lists@gmail.com>> wrote:

John.

One defense comes to mind: there is talk of Swift aiming at systems programming. Is writing a threaded interpreter loop within the potential scope of Swift? That’s a use case that could make use of both `fallthrough` and `goto` (computed goto, really).

switch op {
case LOAD_INDIRECT:
   in0 = memory[in1]
   fallthrough
case LOAD:
   out0 = memory[in0]
//...
}

I am personally interested in the prospect of a language that can scale up to high-level concepts and down to “portable assembler,” but I don’t know if that is the right direction for Swift’s evolution.

Cheers,
John

On Dec 4, 2015, at 2:42 PM, John McCall <rjmccall@apple.com <mailto:rjmccall@apple.com>> wrote:

On Dec 4, 2015, at 2:33 PM, Kevin Ballard <kevin@sb.org <mailto:kevin@sb.org>> wrote:
It's not actually Duff's Device. Duff's Device relies on the fact that C switch statements don't actually introduce a new scope, and so it overlaps a switch with a do-while loop. This lets it only test the number of bytes once, to jump into the middle of the loop, and then it switches over to a while loop that decrements a counter every 8 instructions. Basically, it's a trick for manual loop unrolling that deals with non-multiple-of-8 counts efficiently.

To be pedantic, C switch statements do introduce a new scope. What Duff’s Device exploits is that switch is allowed to jump into (almost) arbitrary scopes, and cases can appear anywhere recursively inside a switch.

But your point that Swift’s switch requires cases to be at the top level within a switch and thus prevents the use of Duff’s Device is 100% correct.

John.

Steve's code is also an example of manual loop unrolling that deals with non-multiple-of-8 counts, but it has calculate the number of bytes on every iteration instead of once. It's a good example of one of the uses of `fallthrough`, it's just not Duff's Device. It's impossible to use Duff's Device in Swift.

-Kevin Ballard

On Fri, Dec 4, 2015, at 02:16 PM, Greg Titus wrote:

Streza’s source code is an example of Duff’s Device, which is a big place where switch fallthrough is arguably the cleanest way to do things and the reason why I’d personally prefer to keep it as part of the language.

On Dec 4, 2015, at 2:12 PM, Erica Sadun <erica@ericasadun.com <mailto:erica@ericasadun.com>> wrote:

Oh let it die, let it die. Any time I use fallthrough I find myself re-factoring to stop using it.

True fact: On all of gist.github.com <http://gist.github.com/&gt;, there are only 22 gist results for "fallthrough language:swift".
Half of those are people just testing out the feature. Most of the remaining ones are just complex cases:
case .Enum1, .Enum2:
expressed as
case .Enum1: fallthrough
case .Enum2:

And then there's streza: Base32.swift · GitHub I'm pretty sure that ponies were harmed in the production of whatever that last bit is.

On Dec 4, 2015, at 3:05 PM, jalkut@red-sweater.com <mailto:jalkut@red-sweater.com> wrote:

In the spirit of some other proposals that remove C or C++ style artifacts, what do folks think about the possibility of removing the "fallthrough" keyword from the language?

My understanding is this keyword is only used for the archaic seeming purpose of perpetuating C-style fallthrough from one switch statement to the subsequent one. The documentation hedges the use of this keyword in forbidding terms that make it clear its use is not encouraged. The presence of the keyword, while an improvement over C’s implicit fallthrough, is a mark of inelegance on an otherwise well-designed, opinionated implementation of swtich statements.

The ugliness of fallthrough’s C-style behavior even demands a caveat in the documentation:

"The fallthrough keyword does not check the case conditions for the switch case that it causes execution to fall into. The fallthrough keyword simply causes code execution to move directly to the statements inside the next case (or default case) block, as in C’s standard switch statement behavior."

To my mind, the caveat explains just what is wrong with fallthrough, both in C or Swift: coded that is clearly labeled with deliberate conditions can nonetheless be reached.

I quipped about this on Twitter, and the most common pushback I got seemed to be from people who either did not know about Swift’s support for comma-separated case statements, or harbored an aesthetic preference for clustering such cases together with fallthrough statements.

In my opinion, unless somebody can think of a strong defense for supporting intentional fallthrough in Swift, removing the keyword would be a move in the direction of minimizing the language’s complexity while also discouraging poor coding style in switch statements.

Thoughts?

Daniel

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

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

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

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

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

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto: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

Is there a reason we cannot use labelled case statements?

    switch some_value {
    case .REFINED:
        if !validate(some_value) { return NULL }
        fallthrough base

    base: case .BASE:
        handle_enum_value();
    }

At least this is explicit now.

···

On Dec 5, 2015, at 10:04 AM, Vinicius Vendramini <vinivendra@gmail.com> wrote:

I understand there might be some cases in which the syntax provided is indeed useful for experienced programmers writing their code. However, in almost all the examples here, I had to struggle to understand the logic behind the code. Not because it’s poorly written... probably because this syntax may be used for many different purposes, so it’s hard to get what exactly is the intent behind each use.

In Pierre’s latest example, for instance, it took me a few seconds to understand what was going on. I know it’s a simplified case, but it seems clearer to me to just write something like

if some_value == .Refined && !validate(some_value) {
  return NULL
}
handle_enum_value()

More complex cases make for a better argument for `switch`es, mainly because they avoid big `if` pyramids, but especially in those I feel the resulting code is significantly harder to understand.

On Dec 5, 2015, at 12:15 PM, Pierre Habouzit <phabouzit@apple.com <mailto:phabouzit@apple.com>> wrote:

On Dec 5, 2015, at 9:02 AM, Chris Lattner <clattner@apple.com <mailto:clattner@apple.com>> wrote:

On Dec 4, 2015, at 2:05 PM, jalkut@red-sweater.com <mailto:jalkut@red-sweater.com> wrote:

In the spirit of some other proposals that remove C or C++ style artifacts, what do folks think about the possibility of removing the "fallthrough" keyword from the language?

I’m not making an argument either way, but I want to point something out: there is a major difference between fallthrough vs ++/c-style-for. To someone who doesn’t know them, the later are "syntactic magic” with no reasonable way to decipher other than looking them up somewhere. The former is an English word whose meaning is obvious in context.

All I’m saying is that to a reader of code, the “badness” of ++ and c-style for loops is greater than the “badness" of fallthrough.

Given that Swift has the goal to also be a low level language, fallthrough is really useful for conciseness and readability.

in system programming C, I find myself writing things like this very often:

switch (some_value) {
case ENUM_VALUE_REFINED:
    if (validate(some_value)) {
        return NULL;
    }
    /* fallthrough */
case ENUM_VALUE_BASE:
    handle_enum_value();
    …
}

Where the swift equivalent would roughly be:

switch some_value {
case .REFINED:
    if !validate(some_value) { return NULL }
    fallthrough
case .BASE:
    handle_enum_value();
}

This is as readable as it gets and is a pattern that the libdispatch has in several places e.g.

Of course, you cannot fall through to arbitrary cases, so things like this C code cannot be done in swift:

switch (some_value) {
case ENUM_VALUE_REFINED_1:
    if (validate(some_value)) {
        return NULL;
    }
    goto base_value;
case ENUM_VALUE_REFINED_2:
    if (validate(some_value)) {
        return NULL;
    }
    goto base_value;

case ENUM_VALUE_BASE:
base_value:
    handle_enum_value();
    …
}

cannot be written in swift, despite also being quite useful.

Jumping between arbitrary points inside a switch is disgusting. jumping from label to label is useful and not harmful especially in swift where you can’t place code between the “switch” and the first case.

-Pierre

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto: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

Is there a reason we cannot use labelled case statements?

    switch some_value {
    case .REFINED:
        if !validate(some_value) { return NULL }
        fallthrough base

    base: case .BASE:
        handle_enum_value();
    }

At least this is explicit now.

that would be awesome.

I understand there might be some cases in which the syntax provided is indeed useful for experienced programmers writing their code. However, in almost all the examples here, I had to struggle to understand the logic behind the code. Not because it’s poorly written... probably because this syntax may be used for many different purposes, so it’s hard to get what exactly is the intent behind each use.

In Pierre’s latest example, for instance, it took me a few seconds to understand what was going on. I know it’s a simplified case, but it seems clearer to me to just write something like

the pattern I showed is really really pervasive in system programming code, especially because in that example below:

if some_value == .Refined && !validate(some_value) {
  return NULL
}
handle_enum_value()

the “validate” is shifted to the right, which hides the essential thing you’re doing, which is the validation.
it is important to me to see the validation stand out and be one indent level away, and not arbitrarily pushed to the right.

it allows to read your code keeping your eyes aligned on the first columns of your text editor to get a sense of the flow of what is going on.

David’s example has this property and I find it very desireable.

···

On Dec 5, 2015, at 10:13 AM, David Owens II <david@owensd.io> wrote:

On Dec 5, 2015, at 10:04 AM, Vinicius Vendramini <vinivendra@gmail.com <mailto:vinivendra@gmail.com>> wrote:

More complex cases make for a better argument for `switch`es, mainly because they avoid big `if` pyramids, but especially in those I feel the resulting code is significantly harder to understand.

On Dec 5, 2015, at 12:15 PM, Pierre Habouzit <phabouzit@apple.com <mailto:phabouzit@apple.com>> wrote:

On Dec 5, 2015, at 9:02 AM, Chris Lattner <clattner@apple.com <mailto:clattner@apple.com>> wrote:

On Dec 4, 2015, at 2:05 PM, jalkut@red-sweater.com <mailto:jalkut@red-sweater.com> wrote:

In the spirit of some other proposals that remove C or C++ style artifacts, what do folks think about the possibility of removing the "fallthrough" keyword from the language?

I’m not making an argument either way, but I want to point something out: there is a major difference between fallthrough vs ++/c-style-for. To someone who doesn’t know them, the later are "syntactic magic” with no reasonable way to decipher other than looking them up somewhere. The former is an English word whose meaning is obvious in context.

All I’m saying is that to a reader of code, the “badness” of ++ and c-style for loops is greater than the “badness" of fallthrough.

Given that Swift has the goal to also be a low level language, fallthrough is really useful for conciseness and readability.

in system programming C, I find myself writing things like this very often:

switch (some_value) {
case ENUM_VALUE_REFINED:
    if (validate(some_value)) {
        return NULL;
    }
    /* fallthrough */
case ENUM_VALUE_BASE:
    handle_enum_value();
    …
}

Where the swift equivalent would roughly be:

switch some_value {
case .REFINED:
    if !validate(some_value) { return NULL }
    fallthrough
case .BASE:
    handle_enum_value();
}

This is as readable as it gets and is a pattern that the libdispatch has in several places e.g.

Of course, you cannot fall through to arbitrary cases, so things like this C code cannot be done in swift:

switch (some_value) {
case ENUM_VALUE_REFINED_1:
    if (validate(some_value)) {
        return NULL;
    }
    goto base_value;
case ENUM_VALUE_REFINED_2:
    if (validate(some_value)) {
        return NULL;
    }
    goto base_value;

case ENUM_VALUE_BASE:
base_value:
    handle_enum_value();
    …
}

cannot be written in swift, despite also being quite useful.

Jumping between arbitrary points inside a switch is disgusting. jumping from label to label is useful and not harmful especially in swift where you can’t place code between the “switch” and the first case.

-Pierre

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

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