Has Java become too complicated?

  • Thread starter frustratedprogrammer
  • Start date
C

Chris Uppal

Mike said:
This is the use of anonymous classes which would be solved equally well by
method pointers, which are conceptually much simpler (or at least more
familiar from other C-base languages.) I find Sun's white paper extolling
the virtues of anonymous classes over method pointers quite unconvincing.

Now there, I agree with Sun (as far as I remember the paper). The guy (I
forget his name -- something Nordic) who introduced them into Delphi (or Object
Pascal or whatever it was then called), went on to introduce them into the
Borland C++ product (where they had no place /at all/), and then went to work
at MS where he has introduced them into everything (it seems) he touches.

The guy's a veritable Typhoid Lizzie. He suffers from some weird obsession
with the concept...

I don't think they have anything to do with, nor are in any way desirable as a
supplement for, OO programming. As an example to support this, in the
Smalltalk I use it is trivial to use the equivalent of "method pointers"
(actually they, MessageSends, are marginally more flexible and powerful).
What's more they are plug-compatible with the less powerful Messages (which
have no bound-in receiver), and with the vastly more powerful (but more
expensive) BlockClosures (which are full, stateful, closures) -- so there is no
barrier to using them whenever they fit the bill. But, in some 8 years as a
Smalltalk user, I have used them twice. Over that same period I must have used
thousands of BlockClosures and Message in contexts where I /might/ have chosen
a MessageSend.

-- chris
 
M

Mike Schilling

Chris said:
Now there, I agree with Sun (as far as I remember the paper). The
guy (I forget his name -- something Nordic)

Anders Helsbeg.
who introduced them into
Delphi (or Object Pascal or whatever it was then called), went on to
introduce them into the Borland C++ product (where they had no place
/at all/),

Hmm? C++ has had method pointers as far back as I can recall. Certainly
they were described in the ARM.
and then went to work at MS where he has introduced them
into everything (it seems) he touches.

I don't know if he was at MS early enough to have introduced them into J++.
He may well have been the one who introduced them into the .NET CLR.

One interesting thing about Sun's white paper is that it was written at a
time when Sun was suing MS for polluting Java with, among other things,
method pointers.
 
C

Chris Smith

Mike Schilling said:
By the way, I think the length and complexity of the conversation we've had
so far is evidence that inner class are pretty complicated :)

Eh? You've been having a conversation about the confusion of saying
that a class has an instance concept. You could have had exactly the
same conversation about incorrect terminology if I had said "the String
class maintains a char[] to store its data". Are instance variables
pretty complicated?
 
C

Chris Uppal

Mike said:
Anders Helsbeg.
Thanks.



Hmm? C++ has had method pointers as far back as I can recall. Certainly
they were described in the ARM.

Not in the same sense as I meant. C++ has had pointers to methods for as long
as I can remember too, but the "method pointers" Helsbeg always squeezes in are
/bound/ method pointers[*] -- fixing not just the method, but also the
receiver. Did you mean something other than those ? I assumed you were
meaning Helsbeg-style "method pointers", since I don't see how pure
pointers-to-methods solve many of the problems addressed by inner classes --
and Java has those anyway, instances of java.lang.reflect.Method.

([*] Actually, now I come to think of it, I'm not certain that he did call them
"method pointers", maybe it was "delegates" ?)

I don't know if he was at MS early enough to have introduced them into
J++. He may well have been the one who introduced them into the .NET CLR.

I think he was (and I think I remember blaming him at the time). I'm not
certain, though, and I haven't tried to check.

One interesting thing about Sun's white paper is that it was written at a
time when Sun was suing MS for polluting Java with, among other things,
method pointers.

Yes, I (too?) have always assumed that there was more than just technical
motivations behind that paper.

-- chris
 
M

Mike Schilling

Chris said:
Eh? You've been having a conversation about the confusion of saying
that a class has an instance concept.

I saw it as being about how inner classes/instances are related to their
enclosing classes/instances. No concept of "enclosing", no discussion.
 
M

Mike Schilling

Chris said:
Mike said:
Anders Helsbeg.
Thanks.



Hmm? C++ has had method pointers as far back as I can recall.
Certainly they were described in the ARM.

Not in the same sense as I meant. C++ has had pointers to methods
for as long as I can remember too, but the "method pointers" Helsbeg
always squeezes in are /bound/ method pointers[*] -- fixing not just
the method, but also the receiver. Did you mean something other than
those ?

That's what I meant. Since this discussion was about complexity of
concepts, I conflated the two, since they're both (more or less) the concept
"object that encapsulates a method call".

I assumed you were meaning Helsbeg-style "method pointers",
since I don't see how pure pointers-to-methods solve many of the
problems addressed by inner classes -- and Java has those anyway,
instances of java.lang.reflect.Method.

Ick. One of the nice things about bound method pointers is that they're
type correct, and far easier to use than instances of Method. There's no
chance of causing any of the "I screwed up the parameters" exceptions, and
no need to package up exceptions thrown by the caller into an
InvocationTargetException.

([*] Actually, now I come to think of it, I'm not certain that he did
call them "method pointers", maybe it was "delegates" ?)

That's what they're called in C#. I don't know what they were called in
J++.
Yes, I (too?) have always assumed that there was more than just
technical motivations behind that paper.

Too, yes :)
 
C

Chris Smith

Mike Schilling said:
I saw it as being about how inner classes/instances are related to their
enclosing classes/instances. No concept of "enclosing", no discussion.

Is there any source of confusion you can point out that doesn't
translate to instance variables rather than inner classes? The only
thing I saw was that when the JLS says "each inner class has ...", it
should have said "each object of an inner class has ...". Other than
that, it's pretty straight-forward.

(Note that I'm not saying there is no complexity involved in the concept
of inner classes. Certainly some of the sequencing of steps involved in
creating them is tricky to understand. I just think it's naive to
believe that tricky issues don't exist with other approaches to those
problems. I also don't see that delegates provide the same advantages,
as they still require the declaration of a named entity "somewhere
else" to accomplish the interactions desired.)
 
C

Chris Uppal

Chris said:
Is there any source of confusion you can point out that doesn't
translate to instance variables rather than inner classes? The only
thing I saw was that when the JLS says "each inner class has ...", it
should have said "each object of an inner class has ...". Other than
that, it's pretty straight-forward.

I don't think so (and I don't think there was all that much actual confusion
involved).

The question (as I see it as an outsider to the conversation) that this
subthread raised is one that I hadn't considered before -- and which I find
quite interesting. Given two objects created in separate runs of a method with
an inner class, what is the class relationship between them ?

Up until this conversation, I would have replied unhesitatingly that they were
of the same class (which is true, of course). But is that the /intended/
picture of the Java design ? Lew has raised the possibility (which I find
plausible) that the intended picture was that that their concrete classes are
unrelated (beyond having a common supertype). Without that assumption, I can't
make any sense at all of the designers' decision not to allow static members in
inner classes -- there is not the slightest semantic or technical advantage in
forbidding them.

This reminds me a bit of the peculiar way that "static" is treated in many
places in Java (Java spec, JVM spec, Java recommended coding conventions). I
have come to believe that the intended picture for static members was that they
were somehow shared between /all/ the instances of a class, rather than that
they were not attached to /any/ instance.

Now to me that picture of "static" is just plain daft. And the banning of
static members of inner classes is daft too. But if that's the way(s) the
designers' minds were running, then at least the daftness is comprehensible.

-- chris
 
M

Mike Schilling

Chris said:
Up until this conversation, I would have replied unhesitatingly that
they were of the same class (which is true, of course). But is that
the /intended/ picture of the Java design ? Lew has raised the
possibility (which I find plausible) that the intended picture was
that that their concrete classes are unrelated (beyond having a
common supertype).

Right. That interpretation would require that each time a Foo.Bar is
created, its type is a subclass of Foo.Bar associated with the enclosing
Foo I reject this by Occam's Razor: it literally multiplies entities
unnecessarily. [1] But I can't disprove it entriely [2], and Lew did a good
job arguing for it.
..
1. And leads to the question: Why is Java creating types dynamically here,
but not with generics where it would actually be useful?

2. Though the fact that foo.bar.getClass() equals the one and only
Foo.Bar.class is strong evidence.
 
K

Karl Uppiano

When Java first become popular I remember it being touted as having
all the nice features of C++ without any of the ugly bits. However as
time goes it seems to be gettiing more and more complicated. The first
backwards step was inner classes and now generics. What does the
future hold?

http://frustrationsofaprogrammer.blogspot.com/

It was also limited and unable to solve some important problems. However, I
think this is a common problem with any technology. Particularly if the
original visionaries have left, and been replaced with less creative and
more propeller-headed engineers.
 
K

Karl Uppiano

Christopher Benson-Manica said:
As a C programmer at heart, it hurts to hear all those lovely C-isms
which still litter C++ referred to as "ugly bits" ;-)


Beauty is in the eye of the beholder, but I think generics actually
made Java look much more becoming. Inner classes are another story...
As with many things, just because a language *allows* you to use
certain constructs doesn't mean you *should*.

Inner classes are a great way of implementing event handlers and callbacks
without cluttering up the outer class's API.
 
C

Chris Smith

Chris Uppal said:
The question (as I see it as an outsider to the conversation) that this
subthread raised is one that I hadn't considered before -- and which I find
quite interesting. Given two objects created in separate runs of a method with
an inner class, what is the class relationship between them ?

Up until this conversation, I would have replied unhesitatingly that they were
of the same class (which is true, of course).

I would have done so, as well. I don't see the other view point. I
read Lew's comments, and I realize that's what he was saying. However,
I just assumed he was trying to see how far he could stretch the JLS
language for fun. It never occurred to me that anyone thinks there is a
reasonable interpretation other than that classes are associated one-to-
one with syntax, such that one bit of syntax (i.e., a piece of code that
declares an inner class) creates one class (within the context of a
given ClassLoader).
This reminds me a bit of the peculiar way that "static" is treated in many
places in Java (Java spec, JVM spec, Java recommended coding conventions).

I am, just like you, sometimes baffled by the choices of the language
with regard to static variables. I am not at all sure that any one
conception of static variables explains all of the oddities in Java's
treatment of statics. Really, you have to trace every one down to
someone's not foreseeing a use somewhere, and following the earlier
precedent to arbitrarily deny the use of static variables when it seems
right.
 
L

Lew

Chris said:
I would have done so, as well. I don't see the other view point. I
read Lew's comments, and I realize that's what he was saying. However,
I just assumed he was trying to see how far he could stretch the JLS
language for fun. It never occurred to me that anyone thinks there is a
reasonable interpretation other than that classes are associated one-to-
one with syntax, such that one bit of syntax (i.e., a piece of code that
declares an inner class) creates one class (within the context of a
given ClassLoader).

Nope. I really was actually trying to follow what I thought Sun was saying,
and I really wastrying to understand inner classes as being bound by their
enclosing instances somehow. I mean, that is what they told me, and perhaps
naively, I tried to twist it into my world view.

That's what I get for treating the JLS as the literal Java Bible, I suppose.

- Lew
 
C

Chris Uppal

Chris said:
The
revolutionary idea is that your choice of building abstractions no
longer has to follow the structural needs of code in terms of
implementing interfaces and such. The general idea of decoupling those
was pretty unprecedented among mainstream OO languages.

I suppose it depends on how you see them. To me inner classes are pretty-much
syntactic sugar for "ordinary" classes. Important syntactic sugar, to be sure,
since they "feel" much less heavyweight than a full top-level class. And that
lightweight feel is important if programmers are to be comfortable using the
kinds of decoupled/inverted code structures they are intended to support.

Their virtue, it seems to me, is almost entirely a matter of perception (a sort
of placebo effect). I agree that they work -- it is now routine to see code
structures which (if expressed as normal classes) would have been considered
"advanced", or even obscure. But it is just a (benign) con-job. Parents try
similar tricks to persuade children to eat their greens ;-)

As useful as it
would have been to be able to access local variables as well, that would
have merely added an implementation technique; it doesn't extend into
the design sphere.

Agreed. For them to extend the design space, they would have to provide
something more like Smalltalk's BlockClosures -- the ability to control
execution in the outer method, not just to share variable bindings with it.

And would probably need to be even lighter-weight syntactically (just for the
same "con-job" reasons).

Is there something you'd prefer?

I'd be quite happy to see it vanish altogether. Defining a method, inside a
class, inside a new() expression, (and usually inside a method call parameter
list, to boot!), is /far/ too much syntax -- unreadable and impossible to lay
out sensibly.

The current syntax opens the door to removing that
restriction in the future without having some clumsy field-copying
syntax left lying about.

I have this bridge you might be interested in buying...

Given that Java lacks first-class functions, I'd say it would have
complicated the language more to add them instead of anonymous classes.

I don't really see that there's all that much difference (assuming that you
don't want full Smalltalk-style closures). Simply take the current inner class
implementation, and restrict the inner class to exactly one method, and bob's
yet uncle. Most of the current syntax for anonymous inner classes then becomes
redundant, and so can be considered implicit and removed. And (ta da!) you
have a nicer and an even lighter-weight syntax with little reduction in
expressive power.

No first class functions necessary ;-)


BTW, I did run a scan of rt.jar from 1.6.0. Out of 15854 classes, 1717 are
inner (of which 1546 are anonymous), and of those 296 (242 anonymous) have more
than one explicit method -- which is a higher proportion than I had expected.

-- chris
 
C

Chris Uppal

Chris said:
I am, just like you, sometimes baffled by the choices of the language
with regard to static variables.

More than just the wording. The lookup algorithm for resolving method calls at
runtime starts by looking for a matching method, and only when one is found
considers whether its static-ness matches the invoking bytecode!

-- chris
 
M

Mike Schilling

Chris said:
More than just the wording. The lookup algorithm for resolving
method calls at runtime starts by looking for a matching method, and
only when one is found considers whether its static-ness matches the
invoking bytecode!

This, I think, is a consequence of the abomination (inherited from C) of
being able to access a static member via a reference as well as via the
class name, and not wanting to have two different sets of lookup rules for
the two cases.
 
D

Dave Glasser

Not everyone is bright enough to be a Java programmer. Maybe that's
the source of your frustration. You're in over your head. I've seen it
before, numerous times, and it's a painful thing to watch, when
someone is totally flummoxed by simple things like inner classes or
generics.

(e-mail address removed) wrote on 22 Feb 2007 02:28:05 -0800 in
comp.lang.java.programmer:
 
L

Luc The Perverse

Dave Glasser said:
Not everyone is bright enough to be a Java programmer. Maybe that's
the source of your frustration. You're in over your head. I've seen it
before, numerous times, and it's a painful thing to watch, when
someone is totally flummoxed by simple things like inner classes or
generics.

While I don't agree with you top posting - I agree with what you said.

Inner classes and generics are useful tools - and for someone who knows how
to program they add a negligible degree of depth to the language.

It's my opinion that there is nothing wrong with being confused about
something, or not understanding something. But to say that there is a
fundamental problem with the system (in this case Java) when you don't even
know what you're talking about is a little offensive.
 
E

Eric Sosman

Mike Schilling wrote On 02/26/07 11:10,:
This, I think, is a consequence of the abomination (inherited from C) of
being able to access a static member via a reference as well as via the
class name, and not wanting to have two different sets of lookup rules for
the two cases.

"Inherited from C?" Since C has no classes, no class
members to be referred to, and no class names to use or not
use as references to those non-existent members of the non-
existent classes, tracing the inheritance seems iffy.
 
T

Tor Iver Wilhelmsen

PÃ¥ Mon, 26 Feb 2007 17:10:55 +0100, skrev Mike Schilling
This, I think, is a consequence of the abomination (inherited from C) of
being able to access a static member via a reference as well as via the
class name, and not wanting to have two different sets of lookup rules
for
the two cases.

I think it has more to do with the "static" modifier not being part of the
method's signature (ie. its unique name) but representing a property of
it. Which can only be checked after finding it by the signature "label".
To differentiate static and non-static methods (with the same signature
otherwise) you would need to add some static/instance component to the
name. And the internal names of methods look mangled enough as it is. :)
 

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,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top