Extend switch .. case statement for all types and simple expressions

Ulf Zibis Ulf.Zibis at gmx.de
Wed Apr 1 02:17:30 PDT 2009


I would like to add, that the MAJOR ADVANTAGE of my proposal is,
that the numerous grades/levels of this proposal could be implemented 
step by step, depending on the complexity of changes, which could be 
done for JDK 7.
More sophisticated grades/levels could be seamlessly added later.
This would be impossible, if the concurring syntax of "Strings in 
switch", which only compares for equality, comes to account.
Also Multiple switch expressions and case ranges 
<http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000213.html> 
could seamlessly be integrated in my proposal.

As I argued more detailed before, default semantic of "switch..case" 
should stay on determining the cases by IDENTITY.
Strings, which are equal, could simply be made identical by String#intern().

Example:
    switch (myStringFromElsewere.intern()) {
        case STRING1 : ...; // all constants are interned by definition
        case STRING2 : ...; //       "            "
        case "foo" : ...; // automatically interned
        case "bar" : ...; //       "            "
        ...
    }

-Ulf


Am 31.03.2009 00:13, Ulf Zibis schrieb:
> AUTHOR(S): Ulf Zibis, Cologne, Germany
>
> OVERVIEW
> FEATURE SUMMARY: Extend switch .. case statement for all types and simple expressions.
> MAJOR ADVANTAGE:
> - Increases readability of source in concurrence to if .. else if .. else syntax.
> - Sophisticated jumps.
> - maybe in some cases javac and hotspot has chance to compute better optimized code.
> MAJOR BENEFIT:
> Stop some programmers escaping to some modern scripting language.
> MAJOR DISADVANTAGE:
> Programmers from other languages, especially C, may be confused about such rich syntax.
>
> EXAMPLES
> SIMPLE EXAMPLE:
> (1):
>      switch( myObject) {
>          case CONSTANT1 : doSomething(); break;
>          case CONSTANT2 : doSomethingElse(); break;
>          default : doSomethingDefault();
>      }
> (2):
>      switch( myString) {
>          case equals("red") : stop(); break;
>          case equals("green") : go(); break;
>          default : openYourEyesForCrossingTraffic();
>      }
> (3):
>      switch( myString) {
>          case equalsIgnoreCase("RED") : sureStop(); break;
>          case equalsIgnoreCase("GREEN") : sureGo(); break;
>          default : beAwareOfPoliceWachtingYou();
>      }
>
> ADVANCED EXAMPLE:
> (4):
>      switch( primitiveInt) {
>          case == 10 : doOnlyIf10(); // alternative syntax for 'case 10:'
>          case < 10 :
>          case >= 20 : break;
>          default : doOnlyInRange();
>      }
> (5):
>      switch( primitiveInt) {
>          case (>= 10 && < 20) : doOnlyInRange();
>          default : throw new Exception("Out of range");
>      }
> (6):
>      switch( myString) {
>          case contains("foo") : doSomething(); break;
>          case regionMatches(true, 2, otherString, 4, 6) : doSomethingElse(); break;
>          default : doSomethingDefault();
>      }
> (7):
>      switch( myString.equals()) { // alternative: myString.equals(..)
>          case "foo" : foo(); break;
>          case "bar" : bar(); break;
>          default : dontCare();
>      }
> (8):
>      switch( className.startsWith("String", ..)) { // alternative: className.startsWith("String", ?)
>          case 0 : doForSimpleName(); break;
>          case 9 : doForFullName(); break;
>          default : canNotDecide();
>      }
> (9):
>      switch( anyObjectOrPrimitive instanceof) { // note, that casting is solved implicit
>          case boolean, byte, ... float : break; // Don't do anything
>          case double : forDouble(anyObjectOrPrimitive);
>          case HashMap :
>          case TreeMap : forPlattformMap(anyObjectOrPrimitive); break;
>          case Map : forOtherMap(anyObjectOrPrimitive); break;
>          default : forObject(anyObjectOrPrimitive);
>      }
> (10): (minimizee chance for NPE)
>      switch( .equals(myString)) { // alternative: ?.equals(myString)
>          case "foo" : foo(); break;
>          case "bar" : bar(); break;
>          default : dontCare();
>      }
> (11):
>      switch( some_lethargic_function_we_cant_call_much().equals(..) ) {
>          case "this":
>          case "that":       this_or_that(); break;
>          case "bigjump":    big();    // fall
>          case "jump":       jump(); break;
>          case "secondlastchance":
>          case "lastchance": last_chance(); break;
>          default:           do_default();
>      }
> .. as replacement for:
>      String sSomeString = some_lethargic_function_we_cant_call_much();
>      if( sSomeString.equals( "this" ) || sSomeString.equals( "that" ) )
>          this_or_that();
>      else if( sSomeString.equals( "jump" ) || sSomeString.equals( "bigjump" ) )
>      {
>          if( sSomeString.equals( "bigjump" ) )
>              big();
>          jump();
>      } else if( sSomeString.equals( "secondlastchance" ) ||
>              sSomeString.equals( "lastchance" ) )
>      {
>          last_chance();
>      } else do_default();
>
> ALTERNATIVES:
> (12):
>      switch( myString) {  // note the '.', I personally would prefer this alternative!
>          case .equals("red") : stop(); break;
>          case .equals("green") : go(); break;
>          default : openYourEyesForCrossingTraffic();
>      }
> (13):
>      switch( primitiveInt) {  // note the '.'
>          case (. >= 10 && . < 20) : doOnlyInRange();
> //        case (? >= 10 && ? < 20) : doOnlyInRange(); // alternative
>          default : throw new Exception("Out of range");
>      }
>
>
> DETAILS
> SPECIFICATION:
> The new syntax should be interpreted as
>      switch ( leftExpressionPart ) {
>          case rightExpressionPart1 :
>          case rightExpressionPart2 :
>          ...
>          default :
>      }
> The result of entire expression should be boolean type.
> There is shortcut for:
>      leftExpressionPart: intVariable
>      rightExpressionPart: == intLiteral
> (the '==' could be ommitted.)
>
> COMPILATION:
> Compiler could first pre-compile to appropriate if..then..else syntax.
> Bytecode would not be affected, but in special cases it could be more compact, if noted 
> pre-compilation would be replaced by sophisticated optimization.
> TESTING:
> Compiler byte-code results for new syntax should be same than from equivalent hand-coded legacy 
> if..then..else syntax
> . Exception: sophisticated optimization.
> LIBRARY SUPPORT: No supporting libraries are needed for the feature?
> REFLECTIVE APIS: There should not be any affection to reflection API.
> OTHER CHANGES: No.
> MIGRATION:
> No refactoring is needed to stay compatible.
>
> COMPATIBILITY
> BREAKING CHANGES:
> No previously valid programs are now invalid.
> ... but ATTENTION:
> If proposals from some other guys regarding "Strings in switch" would be taken into JDK 7, there 
> won't be any compatible way to implement my more general proposal in future version of JDK !!!
> --> So switch .. case statement should compare for IDENTITY if not syntactically determined otherwise.
> --> compare for EQUALITY would also break semantic of existing switch .. case statement.
> Another reason, why I'm against comparing for equality by default syntax, is, that it is good 
> practice to use String constants instead of widely spreaded String literals with same signature for 
> numerous reasons (performance, error prone, ...). The "only-for-String" syntax would lead 
> programmers to stay on widely spreaded String literals of same value.
> If constant is not available for switch variable (e.g. if read from stream), variable could be 
> internalized before, so it's instance becomes identical to the existing constant.
> ===>> If just "Strings in switch" is taken over for JDK 7, there is NO NEED, to compare for equality.
> EXISTING PROGRAMS:
> Source and class files of earlier platform versions interact with the feature without any notice.
>
> REFERENCES
> http://mail.openjdk.java.net/pipermail/coin-dev/2009-February/000001.html
> http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000213.html
> http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000855.html
> http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/001089.html
> http://forums.java.net/jive/thread.jspa?messageID=27781&#27781
> http://forums.java.net/jive/thread.jspa?messageID=15769&#15769
> http://forums.java.net/jive/thread.jspa?messageID=27773&#27773
> http://forums.java.net/jive/thread.jspa?messageID=11393&#11393
> http://lasu2string.blogspot.com/2008/12/string-switch-small-language-changes-on.html
> EXISTING BUGS:
> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5012262
> URL FOR PROTOTYPE (optional):
>
>
>
>
>
>
>
>   



More information about the coin-dev mailing list