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
disasters.
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
regexps.
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/:
System.out.println(m.group(1));
break;
case /barbaz+/:
//etcetera
}
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