light weight types

L

Lew

Arne said:
It was new syntax when it was added.

So was the "assert" keyword. So were anonymous classes. Heck, the Java
language itself was new when it first came out. Come on.
 
R

Roedy Green

You did one of the things I like to see in docs, start with the simple
case and gradually add the complexities.

The other thing you did that I like was introduce the need for a
feature before diving into the specifics of how it work,
--
Roedy Green Canadian Mind Products
http://mindprod.com

I advocate that super programmers who can juggle vastly more complex balls than average guys can, should be banned, by management, from dragging the average crowd into system complexity zones where the whole team will start to drown.
~ Jan V.
 
A

Arne Vajhøj

Lew said:
So was the "assert" keyword. So were anonymous classes. Heck, the Java
language itself was new when it first came out. Come on.

Most new features add complexity.

That was the point in what I was trying to explain.

New features adds complexity whether they add new keywords or
not. So "<T>" or "of T" does not make a big difference in
the complexity added.

Arne
 
L

Lew

Arne said:
Most new features add complexity.

That was the point in what I was trying to explain.

New features adds complexity whether they add new keywords or
not. So "<T>" or "of T" does not make a big difference in
the complexity added.

That is true. But economics teaches us that expenditures already made are
"sunk costs" and no longer part of the cost-benefit analysis.

My point was that we've already added '<T>' so there's no point in worrying
about "of T".
 
R

Roedy Green

I had that "ah-hah" moment. I'm sorry that you haven't, yet.

I go through these descriptions. For the most part I think I
understand all the little pieces, but it just does not hang together.
To use it, I end up using some pat little recipes, or trying to find a
class similar to what I am trying to do. I can't just write the stuff
off the top of my head the way I can all the rest of Java.

Some of the things Joshua Cramer said about the PURPOSE of the various
bits of syntax is helping to create frame to hang the individual bits
of lore on.

Perhaps another few rounds through the essays will make more sense now
I have some practical experience under my belt.

It just bugs me that specifying the contents of a container should be
any more complicated that specifying the contents of an array. There
must be some mistake. Perhaps what is needed in building to concept
of container into the language as deeply as arrays are. You are
resigned that this is a fundamental complexity of the universe, not
the result of political expedience, incompetence or laziness on the
part of the generics implementation designers. I am not yet convinced.
I don't understand it and why it was designed that way well enough.

There does not seem to be sufficient benefit to justify all the fuss.

Another way of putting it, generics are so hairy, they are almost more
likely to introduce more bugs than they prevent, at least temporarily.

--
Roedy Green Canadian Mind Products
http://mindprod.com

I advocate that super programmers who can juggle vastly more complex balls than average guys can, should be banned, by management, from dragging the average crowd into system complexity zones where the whole team will start to drown.
~ Jan V.
 
R

Roedy Green

What List[Integer] has going for it is that the array syntax fits closer
into a notation of what a generics type generally does: it's a container
of some object. On the other hand, it looks like an array access, which
means that the parser would look rather interesting.

Other languages use array syntax for indexing Maps by string for
lookup. But that still does not describe the type of the elements in
the collection.
--
Roedy Green Canadian Mind Products
http://mindprod.com

I advocate that super programmers who can juggle vastly more complex balls than average guys can, should be banned, by management, from dragging the average crowd into system complexity zones where the whole team will start to drown.
~ Jan V.
 
R

Roedy Green

What List[Integer] has going for it is that the array syntax fits closer
into a notation of what a generics type generally does: it's a container
of some object. On the other hand, it looks like an array access, which
means that the parser would look rather interesting.

& is used where you would expect to use comma. extends is used where
you would expect to use implements. super does not mean super.

I suspect the syntax would work just as well with () as <>, perhaps
with minor tweaking such as a "contains" keyword. < and > are already
taken. This is like C++ recycling >> for i/o.

The incompatibility of generics and arrays, and the inability to even
write the simplest Collection without a warning is just not good
enough. There is something fundamentally wrong with the design if such
uglinesses appear unavoidable.

In writing my own code, when something like this happens, it means I
got off on the wrong foot in my mental model quite early on. I have
to backtrack and completely rethink the problem. Then usually I will
be rewarded with something so simple I later wonder why I did not
think of it right of the bat.

The difference is I can presume some quite bright people like Bill Joy
chewed on this, and felt my same distress, but could not come up with
a simpler formulation.
--
Roedy Green Canadian Mind Products
http://mindprod.com

I advocate that super programmers who can juggle vastly more complex balls than average guys can, should be banned, by management, from dragging the average crowd into system complexity zones where the whole team will start to drown.
~ Jan V.
 
R

Roedy Green

Introducing new keywords is an issue I didn't discuss, but suffice to
say that it's something that many of the people with a say in the future
of Java want to avoid.

As a practical problem I think new keywords/reserved words are
overrated.

Old compiled code containing variables named after keywords causes no
problem. A global search-replace, which I do dozen times a day in my
IntelliJ IDE, would handle any code needing recompilation.

It would be highly improbable an existing program would suddenly have
new meaning because of a new keyword. It would nearly always just stop
compiling. It would continue to compile with a -source 1.6 option.

--
Roedy Green Canadian Mind Products
http://mindprod.com

I advocate that super programmers who can juggle vastly more complex balls than average guys can, should be banned, by management, from dragging the average crowd into system complexity zones where the whole team will start to drown.
~ Jan V.
 
L

Lew

Roedy said:
& is used where you would expect to use comma. extends is used where
you would expect to use implements. super does not mean super.

I assume you're talking about something like

public class Foo
<T extends Collection<?> & Comparable<? super T>>

I don't know why you would expect a comma where '&' is used - that would be
incredibly ambiguous. Commas between type parameters represent different type
parameters, i.e., where more than one type is specified:

Map <T extends Foo, U extends Bar>

Replacing '&' in intersection types (and doesn't '&' communicate the idea of
"intersection" just perfectly?) with a comma would conflict with that usage.

Why would "implements" be better than "extends"? The supertype doesn't have
to be an interface. The idea of "extension" is much more natural for type
analysis than "implementation". Really, "implementation" is not at all a
natural concept for type analysis.

And how does "super" not mean super? The type that is "super" ('?' in the
example here) is a supertype; using "super" as the keyword seems entirely natural.

And why are we bitching about this five-year-old syntax anyway? It's a done
deal. Java already has generics defined the way Java already has generics
defined. It will be far, far more productive to learn the syntax than to try
to change it. Especially if the proposed changes are far, far less sensible
than the status quo.
 
T

Tom Anderson

Why would "implements" be better than "extends"? The supertype doesn't
have to be an interface. The idea of "extension" is much more natural
for type analysis than "implementation".

The supertype also doesn't have to be a class. This:

List<? extends Runnable>

Is unnatural.
And how does "super" not mean super? The type that is "super" ('?' in
the example here) is a supertype; using "super" as the keyword seems
entirely natural.

Before generics, super meant exactly one thing: "the method with this
signature in the parent class of the class in which the current method is
defined". That's completely unrelated to it use in generics.
And why are we bitching about this five-year-old syntax anyway? It's a done
deal.

Oh, what, and now we can't bitch about done deals? I'm afraid i didn't get
that memo.
Java already has generics defined the way Java already has generics
defined. It will be far, far more productive to learn the syntax than
to try to change it.

Is Roedy trying to change it? Don't be absurd. He's just complaining about
it.

Now, you could say that complaining about things you really can't change
is a waste of energy, and then i might well agree with you. But you're
tilting at a straw, er, windmill here.

tom
 
T

Tom Anderson

The "?" can represent either a class that implements Runnable or an
interface that extends it. There are a total of three cases, class
extends class, interface extends interface, and class implements
interface. "extends" is appropriate for two of the cases, and the same
keyword has to handle class implements interface and interface extends
interface, so I think "extends" is the less bad choice.

Absolutely. It's still counterintuitive.

Anyway, why only have one keyword there? Why not allow either "extends" or
"implements" there, with the same meaning?
Perhaps it was a mistake to use a special keyword for introducing an
interface in a class declaration. If the superclass and all interfaces
had been introduced by "extends" the problem would not exist.

Hey, we could just have used a colon.
In the first statement of a constructor, "super" introduces the
superclass constructor parameter list. It has never had only one meaning.

That's a call to the constructor with the given signature in the parent
class of the class in which the current method is defined. It has exactly
the same meaning as when used to make a super method call.
In general, Java has gone with a strategy of a short list of reserved
words, recycling them to deal with several related concepts whenever
possible in preference to adding new ones. The most extreme case of this
is "static".

Is it? Doesn't that just mean a feature lives in the class rather than the
instance? I'd nominate "final" for most overloaded, i think.

tom
 
R

Roedy Green

this code snippet does not compile: the contents of 'a' cannot be
silently converted to the 'List<Object>' type. Why so ? Because the list
instance does NOT know it element type. Generics work by so-called 'type
erasure'

That is one of my conjectures, that type erasure was a wrong-headed
idea. It weakened and complicated generics too much. Surely, it is not
inherent to the notion that containers should be type safe.

Think of it this way. How is an ArrayList different from an array?
Basically all it does is automatically grow when it overflows. I
could imagine a Java-like language where growing happened
automatically to arrays. Why should the ability to grow suddenly
require all this additional complexity? Why should Maps (which are a
sort of Array with Object indexes) be all that much more complicated
that arrays?

One way to answer me is to show that the problem is intrinsically
complicated, even without type erasure. I don't think we should
surrender to this mess without a fight, or at least a good
explanation.

Part of my skepticism comes from implementing my own language,
Abundance, back in the early 80s where growing arrays, maps and files
were all handled with the same syntax as arrays.
--
Roedy Green Canadian Mind Products
http://mindprod.com

I advocate that super programmers who can juggle vastly more complex balls than average guys can, should be banned, by management, from dragging the average crowd into system complexity zones where the whole team will start to drown.
~ Jan V.
 
M

Mike Schilling

Roedy said:
That is one of my conjectures, that type erasure was a wrong-headed
idea. It weakened and complicated generics too much. Surely, it is
not
inherent to the notion that containers should be type safe.

Erasure is needed for compatibility with the non-generic version of
the type, and that's the only reason it exists. If generics had been
present from the beginning, the type parameters would be first-class
parts of the type, just as they are for arrays. (And just as they
are in .NET, where generics were used only in newly introduced
classes.)
 
L

Lew

Roedy said:
That is one of my conjectures, that type erasure was a wrong-headed
idea. It weakened and complicated generics too much. Surely, it is not
inherent to the notion that containers should be type safe.

I like type erasure. It keeps one from the temptation to use genericity as an
operational concept as opposed to a declarative one.
 
M

Mike Schilling

Lew said:
I like type erasure. It keeps one from the temptation to use
genericity as an operational concept as opposed to a declarative
one.

I almost know what this means, but every time I think I've grasped it,
my hand seems to be empty. Could you elaborate?
 
L

Lew

Mike said:
I almost know what this means, but every time I think I've grasped it,
my hand seems to be empty. Could you elaborate?

As it stands, generics provide a compile-time contract for declarations about
type relationships. In order to get run-time behavior, i.e., operational use
of type information you need to provide a Class object; type parameters don't
permit any run-time operations.

The result is that generics provide compile-time assertions that code will not
throw a ClassCastException or other type-related problem. Erasure guarantees
that this safety carries no run-time overhead.

Run-time generics would sacrifice this efficiency and tempt us to patch holes
in the type analysis with procedural hacks. Instead of analyzing the types
we'd coerce them. Java still lets you do run-time type tricks with a type
token (Class object), but type parameters are reserved for assertions about
type relationships. This forces us to deal with type problems at compile time.

It's a well-known truth that catching and preventing bugs at compile time is
far superior to dealing with them at run time.

It is true that certain shortcomings exist with the erasure approach, but the
advantages make it worth it.
 
M

Mike Schilling

Lew said:
As it stands, generics provide a compile-time contract for
declarations about type relationships. In order to get run-time
behavior, i.e., operational use of type information you need to
provide a Class object; type parameters don't permit any run-time
operations.
The result is that generics provide compile-time assertions that
code
will not throw a ClassCastException or other type-related problem.
Erasure guarantees that this safety carries no run-time overhead.

Run-time generics would sacrifice this efficiency and tempt us to
patch holes in the type analysis with procedural hacks. Instead of
analyzing the types we'd coerce them. Java still lets you do
run-time type tricks with a type token (Class object), but type
parameters are reserved for assertions about type relationships.
This forces us to deal with type problems at compile time.

Got it. You don't want people codeing

if (T.class.isSubclassOf(Number.class))

Is this really an issue, though? In principle you could do that with

void method( Object[] o)
{
if (o.getClass().getComponentType()
isSubclassOf(Number.class))
...
But I've never seen anything like that.
 
M

Mike Schilling

Peter said:
Though, .NET illustrates that an alternative approach would have
been
to simply create a new, parallel group of classes supporting
generics, rather than to insist that the old classes be reusable via
generics.

It's technically feasible, sure, but given the amount of existing Java
code when 1.5 was introduced, imagine the dumbfoundment with which a
new and incompatible set of, e.g. collections classes (and, far worse,
collection interfaces) would have been greeted.
 
A

Arne Vajhøj

Mike said:
Erasure is needed for compatibility with the non-generic version of
the type, and that's the only reason it exists. If generics had been
present from the beginning, the type parameters would be first-class
parts of the type, just as they are for arrays. (And just as they
are in .NET, where generics were used only in newly introduced
classes.)

Java could have gone for java.util.generic !

Arne
 

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,754
Messages
2,569,522
Members
44,995
Latest member
PinupduzSap

Latest Threads

Top