Java String comparison

T

Thomas G. Marshall

Chris Uppal coughed up:
And just a small correction: String.compareTo)Object) does still
exist. Its implementation, translated back into Java would read:

public int
compareTo(Object o)
{
return compareTo((String)o);
}

It's that damnable covariant hack again...

-- chris

Then where in 1.5.0 java/lang/String.java do you find it? I looked, and
there is no implementation for it, nor even /implied/ implementation due to
generics.
 
T

Thomas G. Marshall

Chris Uppal coughed up:
Thomas said:
:) And thank /GOD/ for that too, by the way.

I am absolutely horrified that I might one day have to design
something big in a procedural language, or even in a language where
methods are alowed to float free from objects. Like that hybrid
language, {cough} C++.

Or indeed, like that clumsy collection of inelegant hacks, kludged
together by committee, and popularly known (in its marketing dept
anyway) as Java 5.

import static java.lang.Math.*;

public class Sin
{
public static void
main(String[] args)
{
double x = PI / 4;
double y = sin(x);
System.out.printf("sin(%f) -> %f", x, y);
System.out.println();
}
}

-- chris

Oh I *KNOW*. Jesus. Drives me nuts too. I was hollering at my screen
every 5 minutes when I was reading much of the proposed slopiness in 5.
However, I will have to say that what you're referring to is still a short
cut. The sin() still belongs to Math, and is not floating in /space/.

You're just given a *freaking horrible* shortcut.
 
T

Thomas G. Marshall

Thomas G. Marshall coughed up:
Chris Uppal coughed up:

Then where in 1.5.0 java/lang/String.java do you find it? I looked,
and there is no implementation for it, nor even /implied/
implementation due to generics.


{author pistol whips himself}

Well, duh. It *doesn't* appear in the String.java, which is entirely your
point. And 5 allows the effective auto-downcasting of something it already
knows to be String underneath, is that what you are saying? I'm feeling a
tad dense this sunday morning, with gobs of caffeine in me before 9:30
already...



--
Iamamanofconstantsorrow,I'veseentroubleallmydays.Ibidfarewelltoold
Kentucky,TheplacewhereIwasbornandraised.ForsixlongyearsI'vebeenin
trouble,NopleasureshereonearthIfound.ForinthisworldI'mboundtoramble,
Ihavenofriendstohelpmenow....MaybeyourfriendsthinkI'mjustastrangerMyface,
you'llneverseenomore.ButthereisonepromisethatisgivenI'llmeetyouonGod's
goldenshore.
 
C

Chris Uppal

Thomas G. Marshall wrote:

[me:]
[...]
And 5 allows the effective auto-downcasting of something it
already knows to be String underneath, is that what you are saying? I'm
feeling a tad dense this sunday morning, with gobs of caffeine in me
before 9:30 already...

It's Monday now, I hope you're feeling more lively...

If a class declares itself to have a method
AType aMethod(AnotherType ac)
then it /must/ provide a method with exactly that name, signature, and return
type. It doesn't matter /how/ it declares itself to possess that method; if it
declares that it implements an interface containing that method then that (for
these purposes) constitues such a "declaration". Since
int compareTo(Object)
is (after erasure) what the Comparable interface requires, that is what String
/must/ provide (whether you can read it in the JavaDoc or not -- or even
whether or not you can see it in the source code).

I wrote that it was that "covariant hack", but I think I was wrong (I'm not
feeling any too bright myself this morning, so I'm not sure either way). It's
clearly using the same appalling hack (automatically generated "invisible"
forwarding methods -- which are not invisible at all) to implement the
semantics, but I don't think that its quite the same language feature that's
being implemented.

-- chris
 
C

Chris Uppal

Thomas said:
However, I will have to say that what you're referring to is still a short
cut. The sin() still belongs to Math, and is not floating in /space/.

Hmm... I disagree. I'd say that static "methods" (why do they call them
"methods" when they are actually functions ?) are floating in space /anyway/.
True, they are subject to class-based access control, and the use the short
form of their names (unqualified form) is subject to class-based scoping too.
But that's just syntactic fluff. If you only consider public static methods,
and if you are willing to use their full names (which is often a good idea,
even if the context is such that you aren't forced to do so), then I don't see
any sense in which they are not just as "loose" as the functions in C++.

Now that Java has added a syntax for making them /look/ loose too, I would say
that the last shred of pretence has been dropped.

import static java.lang.System.*;
import static java.util.Math.*;
import static java.util.Arrays.*;
import static java.util.Collections.*;

How long before we start seeing that kind of thing in "real" code ?

(Actually, I think an argument could be made that the problem isn't the new
import static syntax at all; it's the static methods themselves. one could
claim that new syntax is really quite transparent, and that it is
consequentially showing the underlying problem more clearly.)

-- chris
 
J

John C. Bollinger

Chris said:
Thomas G. Marshall wrote:




Hmm... I disagree. I'd say that static "methods" (why do they call them
"methods" when they are actually functions ?) are floating in space /anyway/.
True, they are subject to class-based access control, and the use the short
form of their names (unqualified form) is subject to class-based scoping too.
But that's just syntactic fluff. If you only consider public static methods,
and if you are willing to use their full names (which is often a good idea,
even if the context is such that you aren't forced to do so), then I don't see
any sense in which they are not just as "loose" as the functions in C++.

Java static methods do have privileged access to objects of their class
and (to some extent) its subclasses, and also to objects of classes in
the same package. (I.e. the flip side of class-based access control.)
Some static methods (albeit not those in java.lang.Math)
fundamentally depend on having this kind of access. In my view, this
makes it quite relevant that static methods belong to particular
classes, and indeed are _not_ just "floating in space".

[...]
(Actually, I think an argument could be made that the problem isn't the new
import static syntax at all; it's the static methods themselves. one could
claim that new syntax is really quite transparent, and that it is
consequentially showing the underlying problem more clearly.)

I agree on that, but I also think that static methods play an important
role in Java. Their role could have been filled in another way (e.g.
full-fledged instance methods on metaclasses), but it had to be filled,
and Gosling & co. chose the way that we now get to complain about.
 
T

Thomas G. Marshall

Chris Uppal coughed up:
Thomas G. Marshall wrote:

[me:]
And just a small correction: String.compareTo)Object) does still
exist. Its implementation, translated back into Java would read:
[...]
And 5 allows the effective auto-downcasting of something it
already knows to be String underneath, is that what you are saying?
I'm feeling a tad dense this sunday morning, with gobs of caffeine
in me before 9:30 already...

It's Monday now, I hope you're feeling more lively...

If a class declares itself to have a method
AType aMethod(AnotherType ac)
then it /must/ provide a method with exactly that name, signature,
and return type. It doesn't matter /how/ it declares itself to
possess that method; if it declares that it implements an interface
containing that method then that (for these purposes) constitues such
a "declaration".

Yes, of course. But....

Since int compareTo(Object)
is (after erasure) what the Comparable interface requires, that is
what String /must/ provide (whether you can read it in the JavaDoc or
not -- or even whether or not you can see it in the source code).

No, because String no longer implements Comparable! It is implementing
Comparable<String>, and comparable is defined as you'd expect:

public int compareTo(T o);

(a generic).

I wrote that it was that "covariant hack", but I think I was wrong

Me too, hence my confusion. I *think* it might be an allowed type matching
from an Object polymorphized to String to a String when used as a Generic,
since the generic ensures that it is a string and only a string. I am not
sure though.
 
T

Thomas G. Marshall

Chris Uppal coughed up:
Hmm... I disagree. I'd say that static "methods" (why do they call
them "methods" when they are actually functions ?) are floating in
space /anyway/. True, they are subject to class-based access control,
and the use the short form of their names (unqualified form) is
subject to class-based scoping too. But that's just syntactic fluff.
If you only consider public static methods, and if you are willing to
use their full names (which is often a good idea, even if the context
is such that you aren't forced to do so), then I don't see any sense
in which they are not just as "loose" as the functions in C++.

Mostly agree. In C sans ++ though you hane no binding option at all, so
it's always, well, floating.
 
T

Thomas G. Marshall

John C. Bollinger coughed up:
Chris said:
Thomas G. Marshall wrote:




Hmm... I disagree. I'd say that static "methods" (why do they call
them "methods" when they are actually functions ?) are floating in
space /anyway/. True, they are subject to class-based access
control, and the use the short form of their names (unqualified
form) is subject to class-based scoping too. But that's just
syntactic fluff. If you only consider public static methods, and if
you are willing to use their full names (which is often a good idea,
even if the context is such that you aren't forced to do so), then I
don't see any sense in which they are not just as "loose" as the
functions in C++.

Java static methods do have privileged access to objects of their
class and (to some extent) its subclasses, and also to objects of
classes in the same package. (I.e. the flip side of class-based
access control.) Some static methods (albeit not those in
java.lang.Math) fundamentally depend on having this kind of access. In my
view, this
makes it quite relevant that static methods belong to particular
classes, and indeed are _not_ just "floating in space".

[...]
(Actually, I think an argument could be made that the problem isn't
the new import static syntax at all; it's the static methods
themselves. one could claim that new syntax is really quite
transparent, and that it is consequentially showing the underlying
problem more clearly.)

I agree on that, but I also think that static methods play an
important role in Java. Their role could have been filled in another
way (e.g. full-fledged instance methods on metaclasses), but it had
to be filled, and Gosling & co. chose the way that we now get to
complain about.

Yep. In the broader sense though, we all complain about everything here...
:)
 
C

Chris Uppal

John said:
Java static methods do have privileged access to objects of their class
and [...] In my view, this
makes it quite relevant that static methods belong to particular
classes, and indeed are _not_ just "floating in space".

Fair point.

-- chris
 
A

AndyRB

Thomas said:
Chris Uppal coughed up:
Thomas said:
ps. isnt it amazing, that classy compiler doesnt even know what
x = sin(y)
means, anymore :)

:) And thank /GOD/ for that too, by the way.

I am absolutely horrified that I might one day have to design
something big in a procedural language, or even in a language where
methods are alowed to float free from objects. Like that hybrid
language, {cough} C++.

Or indeed, like that clumsy collection of inelegant hacks, kludged
together by committee, and popularly known (in its marketing dept
anyway) as Java 5.

import static java.lang.Math.*;

public class Sin
{
public static void
main(String[] args)
{
double x = PI / 4;
double y = sin(x);
System.out.printf("sin(%f) -> %f", x, y);
System.out.println();
}
}

-- chris

Oh I *KNOW*. Jesus. Drives me nuts too. I was hollering at my screen
every 5 minutes when I was reading much of the proposed slopiness in 5.
However, I will have to say that what you're referring to is still a short
cut. The sin() still belongs to Math, and is not floating in
/space/.

Like in c++ where sin() /floats/ in std namespace??
std::sin();

I suppose they could have had sin() belong to some nested namespace
instead:
std::math::sin();
 
A

Andrew McDonagh

Chris said:
Thomas G. Marshall wrote:




Hmm... I disagree. I'd say that static "methods" (why do they call them
"methods" when they are actually functions ?) are floating in space /anyway/.
True, they are subject to class-based access control, and the use the short
form of their names (unqualified form) is subject to class-based scoping too.
But that's just syntactic fluff. If you only consider public static methods,
and if you are willing to use their full names (which is often a good idea,
even if the context is such that you aren't forced to do so), then I don't see
any sense in which they are not just as "loose" as the functions in C++.

Now that Java has added a syntax for making them /look/ loose too, I would say
that the last shred of pretence has been dropped.

import static java.lang.System.*;
import static java.util.Math.*;
import static java.util.Arrays.*;
import static java.util.Collections.*;

How long before we start seeing that kind of thing in "real" code ?

(Actually, I think an argument could be made that the problem isn't the new
import static syntax at all; it's the static methods themselves. one could
claim that new syntax is really quite transparent, and that it is
consequentially showing the underlying problem more clearly.)

-- chris

I don't have to wait at all - there's some guys I know seem to thing its
much 'better' to write these functions than to create an object and call
a method upon it.

crazy but there you go.
 
T

Thomas G. Marshall

Andrew McDonagh coughed up:
I don't have to wait at all - there's some guys I know seem to thing
its much 'better' to write these functions than to create an object
and call a method upon it.

crazy but there you go.


Not just crazy, but /strong/ evidence of the lack of seniority. Very junior
guys might make such a stupid argument. *might*.
 
C

Chris Uppal

Thomas said:
No, because String no longer implements Comparable! It is implementing
Comparable<String>, and comparable is defined as you'd expect:

public int compareTo(T o);

(a generic).

But after erasure (which is not an implementation detail but will apparently
form part of the Java5 language spec), the Comparable<X> family of interfaces
reduce to:

public interface java.lang.Comparable
{
int compareTo(java.lang.Object o);
}

which is why String /must/ have that exact method (not being an abstract
class).

(One can reason similarly at the JVM level using the published spec for
classfiles' semantics -- but of course that depends on the assumption that you
are compiling Java to JVM bytecodes.)

Me too, hence my confusion. I *think* it might be an allowed type
matching from an Object polymorphized to String to a String when used as
a Generic, since the generic ensures that it is a string and only a
string.

I'm afraid I don't follow that sentence. Anyway it seems to be an example of a
hack that I hadn't previously realised they were indulging in. Like the
"covariant hack", it's faking overriding by methods that are formally
unrelated. Erased(Comparable<X>) requires int compareTo(Object), but the
generics stuff require that String.compareTo(String) seems to override (i.e.
implement) that method -- which of course it doesn't. So there's a hack in
there.

What's more its doing it with /co/variant parameter types, rather than
contravariant[*] (hence the cast), which makes it seem even /more/ of a hack to
me....

([*] I'm not sure I've got the terminolgy right here, but I hope you see what I
mean.)

-- chris
 
T

Thomas G. Marshall

Chris Uppal coughed up:
But after erasure (which is not an implementation detail but will
apparently form part of the Java5 language spec), the Comparable<X>
family of interfaces reduce to:

public interface java.lang.Comparable
{
int compareTo(java.lang.Object o);
}

which is why String /must/ have that exact method (not being an
abstract class).


I disagree with that. That's not what erasure means. Erasure *does* in
fact (as you suggest) wipe clean the type information (after the syntax
checking is performed), but it does not /require/ that the stripped down
type (to Object) is honored in itself as an interface contract.

In other words, the results of what happens after the erasure may in fact
look like compareTo(Object) but you could never call it that way because the
compiler only regards that as something it is doing behind your back and not
something you are meant to access as such. If there is no compareTo(Object)
specified by you, there is no compareTo(Object) callable by you.

Erasure will take the <T> parameters out, and insert the down-casts
necessary that may otherwise [probably] be missing. But that's only to get
it to compile. It is merely a mechanism of the compiler to allow backward
compatibility with generics.

In 1.5.0, String.java does /not/ have to have

int compareTo(Object o)

because the generics made it effectively an

int compareTo(String o)

As evidenced by the fact that you cannot call it with an Object object. The
following compiles just fine, with only a compareTo(String) implemented, and
cannot be called with an Object:


<QUOTE from 1.5.0-beta2>
$ cat Gen1.java


package experiments.simple;


public class Gen1
{
public static void main(String[] args)
{
Object str = "hello";
(new Thing()).compareTo(str);
}
}


class Thing implements Comparable<String>
{
public int compareTo(String arg)
{
System.out.println(arg);
return 0;
}
}
$ !com
com Gen1.java
Gen1.java:11: compareTo(java.lang.String) in experiments.simple.Thing cannot
be
applied to (java.lang.Object)
(new Thing()).compareTo(str);
^
1 error


</QUOTE>


....[rip]...

--
Enough is enough. It is /not/ a requirement that someone must google
relentlessly for an answer before posting in usenet. Newsgroups are
for discussions. Discussions do /not/ necessitate prior research. If
you are bothered by someone asking a question without taking time to
look something up, simply do not respond.
 
T

Thomas G. Marshall

Thomas G. Marshall coughed up:
Chris Uppal coughed up:
But after erasure (which is not an implementation detail but will
apparently form part of the Java5 language spec), the Comparable<X>
family of interfaces reduce to:

public interface java.lang.Comparable
{
int compareTo(java.lang.Object o);
}

which is why String /must/ have that exact method (not being an
abstract class).


I disagree with that. That's not what erasure means. Erasure *does*
in fact (as you suggest) wipe clean the type information (after the
syntax checking is performed), but it does not /require/ that the
stripped down type (to Object) is honored in itself as an interface
contract.
In other words, the results of what happens after the erasure may in
fact look like compareTo(Object) but you could never call it that way
because the compiler only regards that as something it is doing
behind your back and not something you are meant to access as such. If
there is no compareTo(Object) specified by you, there is no
compareTo(Object) callable by you.
Erasure will take the <T> parameters out, and insert the down-casts
necessary that may otherwise [probably] be missing. But that's only
to get it to compile. It is merely a mechanism of the compiler to
allow backward compatibility with generics.

In 1.5.0, String.java does /not/ have to have

int compareTo(Object o)

because the generics made it effectively an

int compareTo(String o)

As evidenced by the fact that you cannot call it with an Object
object. The following compiles just fine,


Sorry. The wording I chose here is very bad. What I meant by "compiles
just fine" is "fails just fine", or in better words:

The following fails to compile just as
you should expect it to,

Apologies for the clumsy wording.


with only a
compareTo(String) implemented, and cannot be called with an Object:


...[rip]...



--
Enough is enough. It is /not/ a requirement that someone must google
relentlessly for an answer before posting in usenet. Newsgroups are
for discussions. Discussions do /not/ necessitate prior research. If
you are bothered by someone asking a question without taking time to
look something up, simply do not respond.
 
C

Chris Uppal

Thomas said:
But after erasure (which is not an implementation detail but will
apparently form part of the Java5 language spec), the Comparable<X>
family of interfaces reduce to:
[...]
I disagree with that. That's not what erasure means. Erasure *does* in
fact (as you suggest) wipe clean the type information (after the syntax
checking is performed), but it does not /require/ that the stripped down
type (to Object) is honored in itself as an interface contract.

I think you'll find (when the spec actually comes out) that it /does/ so
require. At least I don't see any way that they can extend the "binary
compatibility" stuff to cope with generics without doing so.

The compatibility stuff is where the /real/ semantics of Java emerge. I.e.
Java as the JVM sees it, not as the compiler writer wishes to pretend it is.

(Aside: Java is not a static language[*], never has /been/ a static language; I
wish they'd stop pretending that it is one.)

-- chris

([*] although as dynamic languages go, it's pretty damned arthritic ;-)
 
T

Thomas G. Marshall

Chris Uppal coughed up:
Thomas said:
But after erasure (which is not an implementation detail but will
apparently form part of the Java5 language spec), the Comparable<X>
family of interfaces reduce to:
[...]
I disagree with that. That's not what erasure means. Erasure
*does* in fact (as you suggest) wipe clean the type information
(after the syntax checking is performed), but it does not /require/
that the stripped down type (to Object) is honored in itself as an
interface contract.

I think you'll find (when the spec actually comes out) that it /does/
so require. At least I don't see any way that they can extend the
"binary compatibility" stuff to cope with generics without doing so.


Well, it currently doesn't require the compareTo(Object), and I doubt it
will ever require that, even if they do decide to hold on to the erasure
technique and enter it into the spec.

It's just not what erasure does, nor is meant to, accomplish.


The compatibility stuff is where the /real/ semantics of Java emerge.
I.e. Java as the JVM sees it, not as the compiler writer wishes to
pretend it is.

(Aside: Java is not a static language[*], never has /been/ a static
language; I wish they'd stop pretending that it is one.)

-- chris

([*] although as dynamic languages go, it's pretty damned arthritic
;-)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,815
Messages
2,569,705
Members
45,494
Latest member
KandyFrank

Latest Threads

Top