JCK feedback on "Strings in Switch" proposal

Reinier Zwitserloot reinier at zwitserloot.com
Mon May 25 08:01:47 PDT 2009

Creating a string switch proposal for equalsIgnoreCase reeks of  
creating the kitchen sink language: Stuff everything into a language  
construct. If that's a good idea, where do we stop? How about  
comparing strings not via case insensitivity, but intended syntactic  
meaning (where á is equal to a to is equal to ä, and ü is equal to  
both 'u' and 'ue', etcetera - java doesn't have this method in a  
library, unfortunately which is why this kind of comparison isn't done  
often, but for obvious reasons, it should be used far more often than  
it is now). You're effectively elevating the concept of a case  
insensitive string comparison to a part of the JLS, whereas currently  
it isn't; it's just 1 library method and 1 static comparator object in  
the String class.

Perl tried this 'everything into the language spec' concept. It's a - 
bad- idea. That sort of language level flexibility can only be gained  
in one way: DSL friendliness in the language. Where ordinary code that  
calls methods on objects can be written so that it looks just like a  
language construct, in other words. Python does quite a bit of this,  
by offering __get__ and __set__ so you can let any object react to  
foo[x] and foo[x] = bar, even __del__ to react to 'del foo', which is  
a python language construct to undefine a variable.

The point is: Java isn't like that. I doubt it ever will be; that just  
makes for a different language altogether. We're going to have to deal  
with that, and not by stuffing every random idea into a language  
feature, or trying to ascertain that language features that are added  
must cover all the bases. Java isn't that flexible, and trying to  
appease all use cases leads to things like EJB 2.0: Unmitigated  

Having said that, I can imagine one way that is easy to remember,  
doesn't try to exert itself too much to try to conform to every use  
case, and is still flexible enough to give people a switch for case  
insensitivity: regexps.

Put regular expressions in the case blocks (with some sort of unique  
identifier, and not just 'parse all string constants into regexps'. We  
don't want to repeat the API mistake of String.replaceAll, after all!

RegExps, via regexp parameters, can configure case insensitivity.  
Requiring that the regexps are constants should also allow as  
sufficiently advanced javac to precompile the regexps, which isn't too  
important, but in a pinch helps performance when using very complex  

Not neccessarily in favour, and for consistency's sake, the special  
regexp notation should be valid anywhere else and be of type  
'Pattern', so it's quite a change, but something to think about.  
Biggest argument against is that you usually want the matcher object,  
which would play havoc with the syntax, you'd have something like:

switch ( Matcher m : someString ) {
    case /foo(.*)bar/:
   case /barbaz+/:

NB: On the topic of doing a direct == comparison: There is really no  
point to ever doing that. Many languages offload this feature  
(reference identity check) to a library call, generally because  
comparing two objects' reference identities is pretty much always the  
wrong thing to do unless you're trying to write a method that tries to  
draw a graph of the way objects are related to each other in memory,  
which is a job for a profiler and not for your code. In java,  
hypothetically, this would be along the lines of  
System.isEqualReference(a, b);. The fact that java's == is used for  
reference identity instead of an amalgamation of a null check and  
an .equals() call results in a proposal to fix this somehow every  
other week, and a lot of headache amongst java coders. Confusion  
around reference identity shows up every other day on freenode's  
##java, for example. That should give some indication as to the wisdom  
of applying reference identity to the string switch idea.

  --Reinier Zwitserloot

On May 25, 2009, at 16:14, Ulf Zibis wrote:

>>> I think it would be better to define "expression == constant" for
>>> several reasons.
>>> (1) "switch..case" syntax historically is expected to be very fast.
>>> See discussions on:
>>>   http://forums.java.net/jive/message.jspa?messageID=4146#4146
>>>   http://forums.java.net/jive/message.jspa?messageID=14216#14216
>>>   http://forums.java.net/jive/thread.jspa?threadID=504
>>> (2) Comparison for identity would better match to legacy semantics  
>>> of
>>> "switch..case" statement.
>> No, it would not.  Comparing strings for "==" equality is a common
>> programming error so the semantics of strings in switch should be
>> defined in terms of .equals equality.
> I think, I got your opinion.
> Variables are equal, if the values of their chunk of bits are  
> identical
> (not generally, but in case of primitives and String objects).
> Variables are identical, if the memory location of their chunk of bits
> is the same. So primitive variables are never identical, as their  
> chunk
> of bits are stored in different memory locations, and pedantically
> argued, "i == j" (for primitives) is always false, they should be
> compared by "i.equals(j)". Theoretically we could define "==" as
> comparison method for the switch..case construct, and accept the upper
> imprecision as legal for primitives. If the programmer wants  
> comparison
> by equals(), he should explicitly write the syntax for it, e.g. in the
> way, I have proposed in my "switch for objects and expressions"- 
> proposal.
> Having this, comparing by "==" can be seen as a programmatically
> shortcut for "equals()" in case of interned String objects (Literals  
> are
> automatically interned by definition).
> There are 3 interesting, widely used types of comparison of Strings:
> - s1 == s1
> - s2.equals(s2)
> - s2.equalsIgnoreCase(s2)
> The first 2 are covered by the given "Strings in Switch" proposal.
> IMHO we should not abandon the attempt to provide a smart syntax for  
> the
> 3rd type of comparison in case of Strings, and even similar for  
> general
> objects.
> if..else constructs seem not to be smart.
> -Ulf

More information about the coin-dev mailing list