Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove required break keyword from switch/case #2047

Closed
sethladd opened this issue Mar 7, 2012 · 18 comments
Closed

Remove required break keyword from switch/case #2047

sethladd opened this issue Mar 7, 2012 · 18 comments
Labels
area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). closed-not-planned Closed as we don't intend to take action on the reported issue type-enhancement A request for a change that isn't a bug

Comments

@sethladd
Copy link
Contributor

sethladd commented Mar 7, 2012

It is an error to omit the break statement from a non-empty case clause. I suggest we omit the break statement from switch/case as it seems redundant and implies that it isn't required.

@DartBot
Copy link

DartBot commented Mar 7, 2012

This comment was originally written by jbloc...@gmail.com


I believe this is a no-brainer. Moreover, I believe that it makes little sense to allow multiple statements after a case label. Dart, like C, C++, Java, JavaScript, and C# is a block structured language! You combine multiple statements into a single statements using a pair of braces. Control flow statements (e.g., for, do, while, if, else) control the execution of a single statement (which may be a block). The switch statement is--and has been since the 1970s--an aberration. It is just wrong to bring this aberration with us into the new millenium. It is trivial to fix, as a matter of specification and implementation. Let's do it.

@DartBot
Copy link

DartBot commented Mar 7, 2012

This comment was originally written by @seaneagan


It would also be more consistent with for, do, while, if, else, to use case(e) instead of case e :.

  switch(x) {
    case (1)
    case (2) print("0 < x < 3");
    case (3) print("x = 3");
    case (4)
    case (5) print("3 < x < 6");
    default print("5 < x");
  }

Which would be even nicer if you could combine cases:

  switch(x) {
    case (1, 2) print("0 < x < 3");
    case (3) print("x = 3");
    case (4, 5) print("3 < x < 6");
    default print("5 < x");
  }

@DartBot
Copy link

DartBot commented Mar 7, 2012

This comment was originally written by jbloc...@gmail.com


Hi Sean. Funny you should mention it. A syntax I suggested a couple of weeks ago was:

switch(x) {
  case(1, 2) {
    print("0 < x < 3");
  } case (3) {
    print("x = 3");
  } case(4, 5) {
    print("3 < x < 6");
  } default {
   default print("5 < x");
  }
}

The sole difference between my proposal and yours is that mine mandates the brackets after each case label (like the do-while statement). I'm not 100% sure how I feel about it, but I like the way it appears similar to a multiway branch implemented as a (nominally nested) if-statement.

@rakudrama
Copy link
Member

+1 to not requiring 'break'.

+-0 to removing 'break' entirely. 'break' might still be useful as a way to
quickly exit an arm of the switch without incurring the nesting of an
if-then-else, somewhat like the clarity of an early exit return.

-1 to requiring parens or braces. It is starting to deviate from 'Dart code
should look familiar', and I find it makes the statements harder to read.

When I read a switch statement, I often scan the whole for the case I am
interested in ("Did I handle foo?"). Making the case labels look just like
other code basically serves to camouflage them. I think Josh's example is
sufficiently hard to read that it makes the point :-)

By removing the need to break, many switch statements are more concise.
Mandatory braces would squander the gains:

  switch (digit) {
    case 0: name = 'zero';
    case 1: name = 'one';
    case 2: name = 'two';
    ...

I would expect the code in an 'arm' between two case labels to be a new scope.
Without fallthrough, these scopes are mutually unreachable, and the whole switch
is alredy in braces to signal that the variables don't survive the switch.

I'm not so convinced about multiple values.

   case 4, 5:

is not such a huge improvement from

   case 4:
   case 5:

when you consider a example with named constants:

  } case (AudioPannerNode.EXPONENTIAL_DISTANCE,
          AudioPannerNode.INVERSE_DISTANCE) {
    xyzzy();
  }

cf

  case AudioPannerNode.EXPONENTIAL_DISTANCE:
  case AudioPannerNode.INVERSE_DISTANCE:
    xyzzy();

In summary, I think we should make a relatively conservative change.
This Dart code:

  case A:
  case B:
    stuff;
    stuff;
  case C:

should behave like this C/Java/JavaScript code:

  case A:
  case B: {
      stuff;
      stuff;
    }
    break;
  case C:

@DartBot
Copy link

DartBot commented Mar 8, 2012

This comment was originally written by @seaneagan


Hi Josh. Independent arrivals at the same conclusion are always a good sign, :-). What's the reason to mandate the brackets ? Also, regarding mapping multiple cases to the same statement, I think something else that can be done is using "patterns" as case expressions, I posted my initial thoughts on this at:

https://groups.google.com/a/dartlang.org/group/misc/browse_thread/thread/e56f45402299f5ac#

@DartBot
Copy link

DartBot commented Mar 9, 2012

This comment was originally written by @seaneagan


The old default for switch statements was to "continue" to the next branch unless you explicitly "break". This was the incorrect default, which is why Dart mandates "break" in case statements. I'm all for this bug, but it makes "break" the only option, there is no way to get back to the old "continue" semantics, which are useful in some cases especially if cases are allowed to do more than just check for == (see https://groups.google.com/a/dartlang.org/forum/#!topic/misc/5W9FQCKZ9aw).

So why not allow the "continue" keyword in case statements to explicitly get back to the old default? The main concern would be that it means you have to use a labeled continue to refer to outer loops.

@DartBot
Copy link

DartBot commented Mar 20, 2012

This comment was originally written by 13thLunati...@gmail.com


hi.

I'm from the discussion on the General Dart Discussion:
  https://groups.google.com/a/dartlang.org/group/misc/browse_thread/thread/3500924a9d1075ab/5553853479c67716

I think, the "break" is unnecessary in a "switch-case" statement of the Dart. my reason and things was write to the discussion, please read if you has interest.

there is a vote to the theme:

  ++vote: omit the "break"

and, with vote optional to a related talk:

  ++vote: a case syntax change to a blockwise from old C-Style compatible syntax

  ++vote: add a pattern match syntax. (I think users as the Dart targeted are need switch syntax even if add a pattern match syntax to the Dart.)

I'm glad to join the discussion. thanks.

@DartBot
Copy link

DartBot commented Mar 20, 2012

This comment was originally written by amat...@gmail.com


Comment #­4 @­sra +1

Empty cases are easier to read since every label name starts at the same point:

case "orange", "yellow", "red", "blue":

case "orange":
case "yellow":
case "red":
case "blue":

@DartBot
Copy link

DartBot commented Mar 20, 2012

This comment was originally written by jjb@google.com


You're assuming that people will actually format "multi-valued case statements" on multiple lines. Many programmers conserve vertical space, so you'll see things like this:

  case "orange": case "yellow": case "red": case "blue":

@DartBot
Copy link

DartBot commented Mar 20, 2012

This comment was originally written by amatias...@gmail.com


I assume than some people write it on multiple lines and some other write it on one line. I've never seen this and found it harder to read, but is up to the programer.

I mean than multiple cases should not be removed for the ones (like me) who prefer many cases on multiple lines.

@sethladd
Copy link
Contributor Author

FYI another user tries Dart switch statements: http://japhr.blogspot.com/2012/03/dart-switch.html

From the post:

"I really do not care for that trailing break. It obscures the intent of the code (the direction assignment), decreasing long-term maintainability. I suppose that I could move it to a separate line, but my switch() statement already has two more lines of code than the equivalent if-statement structure.

The only time that I can think to use the switch statement in Dart code is when I have significant, multi-line calculation to perform for each case. Even then it might be better to break those mulii-line statements out into separate functions.

Which begs the question: is there a use-case for Dart's switch()? Unless I can think of one, I may give it a miss in Dart for Hipsters."

@sethladd
Copy link
Contributor Author

I propose a "baby step" to help deal with this issue.

Can we make a missing break for non-empty case clauses a static warning, or better yet a compile time error? The fact that you don't find out about this missing syntax until runtime is the most unsettling to me.

@rakudrama
Copy link
Member

Seth: I don't think the "baby step" is in the right direction.
It makes the break necessary, which is the opposite of what I suggested in #­4.
Small switch statements look a lot cleaner without the break.

If a static check is implmented, to needs to do some control flow: example - a warning for a missing break following a return, throw, or continue would be irritating.

@gbracha
Copy link
Contributor

gbracha commented Apr 12, 2012

Added Duplicate label.
Marked as being merged into #2354.

@gbracha
Copy link
Contributor

gbracha commented Jun 26, 2012

Issue #3701 has been merged into this issue.

@sethladd
Copy link
Contributor Author

Added WontFix label.
Marked as being merged into #.

@sethladd sethladd added Type-Enhancement area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). labels Dec 26, 2013
@rakudrama rakudrama mentioned this issue Jun 3, 2015
@kevmoo kevmoo added closed-not-planned Closed as we don't intend to take action on the reported issue type-enhancement A request for a change that isn't a bug and removed resolution-wont_fix labels Mar 1, 2016
@hyjfine
Copy link

hyjfine commented Sep 20, 2018

just something like kotlin when?
when (x) {
in 1..10 -> print("x is in the range")
in validNumbers -> print("x is valid")
!in 10..20 -> print("x is outside the range")
else -> print("none of the above")
}

copybara-service bot pushed a commit that referenced this issue Apr 3, 2023
…s, markdown, matcher, mockito, path, pool, source_map_stack_trace, sse, stream_channel, string_scanner, test, test_reflective_loader, tools, typed_data, webdev

Revisions updated by `dart tools/rev_sdk_deps.dart`.

cli_util (https://github.com/dart-lang/cli_util/compare/91747f7..6c318c2):
  6c318c2  2023-04-02  dependabot[bot]  Bump dart-lang/setup-dart from 1.4.0 to 1.5.0 (#81)
  df83fb5  2023-04-02  dependabot[bot]  Bump actions/checkout from 3.3.0 to 3.5.0 (#80)

collection (https://github.com/dart-lang/collection/compare/0d0e184..30fd0f8):
  30fd0f8  2023-04-02  dependabot[bot]  Bump actions/checkout from 3.3.0 to 3.5.0 (#277)

dartdoc (https://github.com/dart-lang/dartdoc/compare/0746cda..9be04e0):
  9be04e0c  2023-03-28  Jonas Finnemann Jensen  Allow ID attributes on headings when running with --sanitize-html (#3358)
  8785dd24  2023-03-27  dependabot[bot]  Bump actions/checkout from 3.3.0 to 3.5.0 (#3377)
  0944fa32  2023-03-27  dependabot[bot]  Bump github/codeql-action from 2.2.6 to 2.2.9 (#3379)
  e318d34f  2023-03-27  dependabot[bot]  Bump dart-lang/setup-dart from 1.4.0 to 1.5.0 (#3378)

ffi (https://github.com/dart-lang/ffi/compare/32f5eef..04fa38a):
  04fa38a  2023-04-03  Daco Harkes  test zero termination of Utf8 string (#147)
  eb93bbb  2023-04-03  dependabot[bot]  Bump dart-lang/setup-dart from 1.4.0 to 1.5.0 (#188)
  2a6b643  2023-04-03  dependabot[bot]  Bump actions/checkout from 3.3.0 to 3.5.0 (#189)

intl (https://github.com/dart-lang/intl/compare/fca552f..a958db0):
  a958db0  2023-03-29  Googler  Internal change

json_rpc_2 (https://github.com/dart-lang/json_rpc_2/compare/0280ac6..aea3bea):
  aea3bea  2023-03-28  Kevin Moore  Fix analysis, bump min SDK to 2.19 (#93)

lints (https://github.com/dart-lang/lints/compare/dfded5e..f09399a):
  f09399a  2023-04-02  dependabot[bot]  Bump actions/checkout from 3.3.0 to 3.5.0 (#110)
  9581bab  2023-03-25  Parker Lougheed  Fix 'recommended' spelling in README (#109)
  c92e1ca  2023-03-23  Michael Thomsen  Update README.md (#108)
  7134608  2023-02-01  dependabot[bot]  Bump actions/checkout from 3.2.0 to 3.3.0 (#98)

markdown (https://github.com/dart-lang/markdown/compare/ecbffa9..d437c85):
  d437c85  2023-04-02  dependabot[bot]  Bump actions/checkout from 3.3.0 to 3.5.0 (#529)
  3550fe6  2023-04-01  dependabot[bot]  Bump subosito/flutter-action from 2.8.0 to 2.10.0 (#528)
  d1b7907  2023-04-01  dependabot[bot]  Bump dart-lang/setup-dart from 1.4.0 to 1.5.0 (#527)
  0daf231  2023-03-31  le.chang  Footnote support (#441)
  b96bc08  2023-03-30  Jonas Finnemann Jensen  Prepare a release of 7.0.2 (#526)

matcher (https://github.com/dart-lang/matcher/compare/dc310d9..61f4347):
  61f4347  2023-03-21  Nate Bosch  Prepare to publish (#214)

mockito (https://github.com/dart-lang/mockito/compare/ed5bd84..28e8eda):
  28e8eda  2023-04-02  dependabot[bot]  Bump dart-lang/setup-dart from 1.4.0 to 1.5.0
  ccb9abf  2023-04-01  dependabot[bot]  Bump actions/checkout from 3.3.0 to 3.5.0
  65ee0c4  2023-03-23  Nate Bosch  Expand pub constraint on test_api (#615)
  e6ea7ad  2023-03-23  Nate Bosch  GitHub Sync (#614)

path (https://github.com/dart-lang/path/compare/24b58a2..cd37179):
  cd37179  2023-04-02  dependabot[bot]  Bump dart-lang/setup-dart from 1.4.0 to 1.5.0 (#139)

pool (https://github.com/dart-lang/pool/compare/694cfd8..338bfb4):
  338bfb4  2023-04-02  dependabot[bot]  Bump dart-lang/setup-dart from 1.4.0 to 1.5.0 (#67)

source_map_stack_trace (https://github.com/dart-lang/source_map_stack_trace/compare/45ea368..08a81a8):
  08a81a8  2023-04-02  dependabot[bot]  Bump actions/checkout from 3.3.0 to 3.5.0 (#37)
  4cbe06e  2023-04-02  dependabot[bot]  Bump dart-lang/setup-dart from 1.4.0 to 1.5.0 (#36)

sse (https://github.com/dart-lang/sse/compare/8c03b73..8c3efdc):
  8c3efdc  2023-04-02  dependabot[bot]  Bump actions/checkout from 3.3.0 to 3.5.0 (#80)
  e35336a  2023-04-02  dependabot[bot]  Bump nanasess/setup-chromedriver from 1.1.0 to 2.0.0 (#81)

stream_channel (https://github.com/dart-lang/stream_channel/compare/a20ccd4..fe0f5e4):
  fe0f5e4  2023-04-02  dependabot[bot]  Bump actions/checkout from 3.3.0 to 3.5.0 (#89)

string_scanner (https://github.com/dart-lang/string_scanner/compare/29e471e..f7a656f):
  f7a656f  2023-04-02  dependabot[bot]  Bump dart-lang/setup-dart from 1.4.0 to 1.5.0 (#56)
  fe8c301  2023-04-02  dependabot[bot]  Bump actions/checkout from 3.3.0 to 3.5.0 (#55)

test (https://github.com/dart-lang/test/compare/cc0598b..a01b185):
  a01b185e  2023-03-30  Nate Bosch  More smoothly handle missing compiler info (#1980)
  b24b4668  2023-03-27  Daco Harkes  Support native assets (#1975)
  c3828267  2023-03-23  Nate Bosch  Prepare to publish (#1974)
  9035bba8  2023-03-21  Parker Lougheed  Use deps.dev for OpenSSF scorecard results link (#1976)

test_reflective_loader (https://github.com/dart-lang/test_reflective_loader/compare/c4c2d5c..a85a930):
  a85a930  2023-04-01  dependabot[bot]  Bump dart-lang/setup-dart from 1.4.0 to 1.5.0 (#46)
  27bc418  2023-04-01  dependabot[bot]  Bump actions/checkout from 3.3.0 to 3.5.0 (#47)

tools (https://github.com/dart-lang/tools/compare/fb2dada..d40ca93):
  d40ca93  2023-04-03  dependabot[bot]  Bump actions/labeler from 4.0.2 to 4.0.3 (#66)
  4185d6d  2023-04-03  dependabot[bot]  Bump coverallsapp/github-action from 1.2.4 to 2.0.0 (#65)
  b14d5be  2023-04-03  dependabot[bot]  Bump actions/checkout from 3.3.0 to 3.5.0 (#64)

typed_data (https://github.com/dart-lang/typed_data/compare/f858046..d85363d):
  d85363d  2023-04-02  dependabot[bot]  Bump dart-lang/setup-dart from 1.4.0 to 1.5.0 (#62)
  0f57d9b  2023-04-02  dependabot[bot]  Bump actions/checkout from 3.3.0 to 3.5.0 (#63)

webdev (https://github.com/dart-lang/webdev/compare/c2c8b17..b139649):
  b139649e  2023-03-31  Elliott Brooks  Don't show non-instantiated variables (#2061)
  8437f60a  2023-03-31  Elliott Brooks  Move project-specific getters to `TestProject` instead of `TestContext` (#2052)
  652e040c  2023-03-30  Elliott Brooks  Provide an app entrypoint to DWDS (#2047)
  0afc9eb4  2023-03-30  Elliott Brooks  Add Dart Code Metrics (#2055)
  5fcbb803  2023-03-29  Elliott Brooks  Apply `trailing-comma` lint (#2054)
  5bd21384  2023-03-28  Elliott Brooks  Skip failing webdev integration_test cases (#2051)
  2d8e9c23  2023-03-24  Elliott Brooks (she/her)  Adds a script for the release steps of `dwds` and `webdev` (#2049)
  afee8c74  2023-03-23  Elliott Brooks (she/her)  Reset `webdev`, `dwds`, `test_common` after publishing (#2048)
  4122b234  2023-03-22  Devon Carew  update to the latest mono_repo generated CI (#2044)
  2b6e9182  2023-03-22  Elliott Brooks (she/her)  Prepare Webdev for `3.0.3` release (#2046)
  c3cbd89b  2023-03-22  Elliott Brooks (she/her)  Prepare DWDS  for 18.0.2 release (#2045)
  bb22b3a0  2023-03-22  Anna Gringauze  Make debugger skip same locations in dart  during stepping. (#2043)
  b9499819  2023-03-20  Anna Gringauze  Prepare for variable names changes due to patterns support in DDC (#2042)

Change-Id: I5b8d591d1b906338564cf008f935b17f85ed2813
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/292922
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Devon Carew <devoncarew@google.com>
copybara-service bot pushed a commit that referenced this issue Jun 29, 2023
…uf, test

Revisions updated by `dart tools/rev_sdk_deps.dart`.

dartdoc (https://github.com/dart-lang/dartdoc/compare/e04a6b3..c2ed703):
  c2ed703c  2023-06-26  dependabot[bot]  Bump ossf/scorecard-action from 2.1.3 to 2.2.0 (#3454)

ecosystem (https://github.com/dart-lang/ecosystem/compare/b1056e6..19fa443):
  19fa443  2023-06-29  Lasse R.H. Nielsen  Clean-up and tweaks of the firehose project. (#117)
  9ef5948  2023-06-27  Moritz  Excise health from firehose (#118)
  36c662e  2023-06-27  Moritz  Introduce a health checking workflow (#115)

http (https://github.com/dart-lang/http/compare/ff1fcfe..d68081f):
  d68081f  2023-06-26  Nate Bosch  Prepare to publish package:http (#973)
  067bff3  2023-06-26  Alex James  Create java http package (#971)

lints (https://github.com/dart-lang/lints/compare/79581ff..89f9519):
  89f9519  2023-06-28  Parker Lougheed  Fix typo in 3.0.0-wip changelog entry (#137)

markdown (https://github.com/dart-lang/markdown/compare/bd6ae8d..4674d09):
  4674d09  2023-06-27  Zhiguang Chen  Fix HtmlBlockSyntax (#548)

mockito (https://github.com/dart-lang/mockito/compare/1d6064a..974226e):
  974226e  2023-06-27  Googler  Internal change

protobuf (https://github.com/dart-lang/protobuf/compare/e76bd74..7bebbc6):
  7bebbc6  2023-06-29  Ömer Sinan Ağacan  Update protoc_plugin Makefile: (#858)
  acc0462  2023-06-29  Ömer Sinan Ağacan  Ignore non-items in message sets (#857)
  0eb3796  2023-06-29  Ömer Sinan Ağacan  Ignore unknown tags in message set items (#856)
  2996e1d  2023-06-27  Ömer Sinan Ağacan  Implement message set wire format (#836)

test (https://github.com/dart-lang/test/compare/cdc8178..021667a):
  021667a4  2023-06-28  Jacob MacDonald  prep to release (#2048)
  3d44fcae  2023-06-28  Yaroslav Vorobev  feat(test): add MOZ_AUTOMATION=1 to ff test runner (#2049)
  6e675f80  2023-06-28  Parker Lougheed  Replace broken link to observatory with DevTools mention (#2047)
  2904779b  2023-06-28  Yaroslav Vorobev  feat(runner): add env overrides for safari and ff (#2042)
  54350282  2023-06-28  Parker Lougheed  Update link from old linter site to dart.dev (#2046)
  8c4b15d1  2023-06-28  Jacob MacDonald  allow the latest analyzer (6.x.x) (#2045)

Change-Id: I86901fb2211adf81288f0940a355d6c33ddd8a7d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/311927
Auto-Submit: Devon Carew <devoncarew@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
@darkstarx
Copy link

Hi guys!
Removing the keyword break is a big mistake! The operator switch is a chain of tests, and you have just broken this chain and haven't left any chance to control the passage of this chain.

With break I can control the process, e.g. like this

final z = 1;
print(z);
switch (z) {
  case 1: print('This is less than two');
  case 2: print('This is less than three');
    break;
  case 3: print(This is three);
    break;
}

It must show

1
This is less than two
This is less than three

Without break the output would be like this

1
This is less than two

Also, since you have left the optional break, it will lead to stupid mistakes of understanding such code. You had to either remove the word break completely, or leave it with the old logic of use.

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). closed-not-planned Closed as we don't intend to take action on the reported issue type-enhancement A request for a change that isn't a bug
Projects
None yet
Development

No branches or pull requests

7 participants