7.0 wishlist?

H

Hendrik Maryns

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Lew schreef:
Andreas Leitgeb schreef:



Not true. I just tried it, and the compiler complains.
$ javac testit/AbstractModel.java testit/Foo.java
testit/Foo.java:51: testit.AbstractModel is abstract; cannot be
instantiated
AbstractModel am = new AbstractModel();
^
1 error

AbstractModel has an explicit public constructor.

Oops, sorry I should have checked that. Then it really makes no
difference, but conceptually, it would indeed make sense to forbid a
public constructor. OTOH, it would mean just having another error message…

H.
- --
Hendrik Maryns
http://tcl.sfs.uni-tuebingen.de/~hendrik/
==================
Ask smart questions, get good answers:
http://www.catb.org/~esr/faqs/smart-questions.html
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.9 (GNU/Linux)
Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org

iEYEARECAAYFAkkJxYEACgkQBGFP0CTku6P9MQCaA9QGhEctkKBYRb7UWjmVv80z
9+IAn2i0Hyk9yAe4OFBhUOLduivdbujN
=LmUl
-----END PGP SIGNATURE-----
 
S

Stefan Ram

Harold Yarmouth said:
There's probably plenty of these floating around already, but here's
bits of mine:

The process for 7.0 seems to be quite advanced now, and decisions
already seems to be made. So, a wishlist might be more
appropriate for 9.0 (with 8.0 being a maintenance release).

* I want the compiler tool and the database of the JDK as a
part of the JRE.

IIRC there are some new provisions for partial loading or
downloading of the rt.jar. If I remember this right, then
this should lower the cost of the inclusion of additional
parts.

Many programs need a means to store data in a database,
and a single standard database would make such
techniques easier to
- port,
- maintain, and to
- learn.

With a runtime compiler, some part of what is now being
done with scripting languages can be done with Java, but
with faster execution. One could have a plug-in directory
with Java source files which are compiled on demand at
run-time.

* Some standard interfaces for functions, values, and
operations to enhance interoperability between libraries
of different vendors. For example,

public interface Function /* java.lang.Function */
< Range, Domain >{ Range valueOf( Domain value ); }
 
A

Andreas Leitgeb

Mike Schilling said:
True, but placing a newly written class in the same package as a library
class so that you can access its package-private bits is pretty evil.

Actually, getting access to any bits not normally accessible is *not*
the point of the discussed proposal.
I've posted examples for that already.
A wrapper class can access just as much of the wrapped class
as can unrelated classes in the same package as the wrapper.
 
M

Martin Gregorie

I'd like to see the 'unsigned' property introduced for the primitive
numeric types. It would useful for dealing with message bodies associated
with protocols that specify octet codings. Id actually like an additional
'octet' primitive but that would cause all sorts of upheavals and in any
case the notation 'unsigned byte|int|long' is more general.

OK, so I'm a C retread, but I'd still find this a useful addition to the
language.
 
A

Andreas Leitgeb

Whereever I say "something is wrong", that of course only
reflects my own opinion. And this opinion is often (but not
always) a result of a misunderstanding. I'm glad if you
point those out, but please don't ever feel offended by them.
They unfortunately happen sometimes.
Some other disagreements are not about misunderstandings,
but about different views of how it should be.

Harold Yarmouth said:
Lack of methods seems like a pretty big distinction between Cloneable
(and Serializable) and "normal" interfaces.

So you do intend a special case for marker interfaces so
marker interfaces need to be explicitly "implemented", but all
others are auto-implemented if all it's method signatures exist.
explicitly implementing a non-marker interface then has only
one purpose: let the compiler make sure I didn't forget a method.

Did I get it right? If so, then I do not like it at all.
If it's still a misunderstanding, then my comment obviously
doesn't really apply to your idea.

How would you judge the *runtime* penalty of checking the existence
of all necessary methods upon each attempted cast?
Eh -- I don't read using Google, and you don't appear to have posted
this using Google, so why would Google distort it?
As Lew guessed right, it was intended for anyone who does read the
posting with google. Btw., That doesn't need to be a gmail'er, but
could be anyone just using google's news-archive at a later time,
as I've frequently done myself in the past. There is no such thing
as a private conversation in a newsgroup.
With the added proviso that extensions of final classes can't see their
protected fields and methods. Essentially, "protected == private if the
class is final" would be maintained.
Yes (furthermore leaving aside the "same-package" special case).
I'd even go further to do this regardless of final'ity
of the wrapped class. It doesn't seem right to me for a
class that *doesn't really* subclass a given class to still
access it's more-restricted bits.
Verbiage alert. This is a slight modifier that would be very
common on reference declarations,
In some way you're right, but Joshua also made a good point
recently by quoting a sample of some new keyword-less syntax
of some "newer C++": just seeing the new syntax makes it
almost impossible to look it up in order to get to know
what it means.
As soon as some keyword or other constant verbiage is used,
it becomes possible to look it up.

However, there are new problems I see with it (non-nullness) now:
Assume I wanted to use a HashMap<String,Integer*> I'd expect it
to only contain non-nulls, but get() would still produce nullable
values, as it returns null for unknown keys. HashMap's implementation
is ofcourse not aware of whether it's Value type is nullable, so it
has no clue as to how to declare it still-nullable when it returns
the Type parameter or null. There may exist solutions, but I fear
it's getting more and more complex, rather than just the simple
nonnull marker you started out with.
String*[] noNullsArray = array; // Runtime check that no element
// is null gets generated here.
Huh!? I thought the whole point of it was to guarantee null-freeness
at compile time.
Compare it with ClassCastExceptions: they can only be thrown at explicit
casts (implicit casts are only possible where no runtime-check is necessary)

Alternative: new method in java.utils.Arrays such that
noNullsArray=Arrays.nonNull(array);
will assign the instance only after a successful runtime nonnull check
(otherwise throw a NullPointerException immediately)
String*[] another = {"Foo", "Bar", "Baz"};
Ok, that's fine, but a special case (only hardwired number
of elements possible).
Of course we could get into hairiness with noting whether the array
reference itself can be null:
String*[]* -- which * means which?
That will need some more and better ideas, expecially also for
multidimensional arrays (i.e. arrays of arrays of arrays ...).
I like the principle, though.
Really little gain, ...
The cases I was thinking of are e.g. [...]
catch (IOException _) {
.... = new ...() { public void actionPerformed (ActionEvent _) {

These cases hardly ever accumulate, but if they do, there's still
"__" and "___" and ... as further dummy names.

(I admit that these cases were not covered by my previous arguments.)
I'm just asking for
Map<Key,Value> map = new HashMap();
without any need to repeat the <Key,Value>, that's all!
Sorry, my misunderstanding once again.
I think I've read that this particular syntax will indeed
be added in 7.0 (regardless of this discussion here).
StringBuilder sb = new(10);
I don't like that at all.
classes be both uninstantiable and unsubclassable. As things stand, you
have to put a private no-argument constructor in, which says the same
thing as "final" but in a much more verbose and less readable manner.

My point is that I see no relevant need to prevent anyone from
instantiating or subclassing a Utility class, e.g. like java.lang.Math.
What bad could one do with it, if it were possible?

Playing around I tried this ugly idiom:
class Test { static Math m; static { m.sin(m.PI); } }
interestingly the bytecode contains "getField m"
immediately followed by "pop".
I think you've misunderstood me. The point was that this would be a
corner case, where the compiler would think that an exception could be
thrown somewhere where it actually wouldn't occur for exactly the
reasons you state.
What did you mean should actually happen to checked exceptions
thrown within run() (and not caught there)?
Why not just least common denominator?
Because such an array may not be compatible with what I want to use it
for:
void foo(Number[] a) ...
foo({1,2,3,5,8,13}); // wouldn't work, because the auto-inferred
type would be Integer[] which is not castable to Number[].
Oh, my God. Uggg-leee!
It's a generalisation. it's about like
try { ... errors caught }
continue { ... errors not caught }
tryalso { ... errors caught again }
continue { ... errors not caught }
tryalso { ... errors caught again }
catch ...
finally ...

except it could be even nested:
try {
for (...;...;...) { // loop header may throw excs to be caught.
dontcatch { doSomething(); } // propagate all errors from that call.
}
} catch (...) { ... } finally {...}

I don't think I'd need the feature myself, but it does
appear to have an aura of usefulness :)
Someone else would have to find a better verbiage for it.

Oh, and the finally block would still need to be executed
even if it was doSomething() that threw an exception.
The existence of IdentityHashMap is proof that someone at Sun also
thought that such a thing could be useful. They just didn't generalize it.
That's a very very special and otherwise rare usecase (serialization helper).

Don't let my opinion against it discourage you.
ReferenceQueue already exists and somewhere there is code that enqueues
references on them. So the "hooking into the GC" at issue here is
already being done.
Sun did a few special tricks to prevent users from hooking in.

I do not exactly understand Sun's reasons for that, but it most
definitely hasn't just been forgotten - it has actively been
worked against by sun.
As it is, I think the effect can be achieved by making a Thread that
calls the blocking poll method
There is no blocking poll for the ReferenceQueue, and also no way to
create one as derivative. The thread would have to run a busy loop
(yuck!).
Referring to the enum implementation, which has the enum constants
actually singleton instances of same-named subclasses.
Thanks for explaining. I really didn't know that.
Not on disk, no, but there are four classes in the system at runtime;
some ClassLoader magic sees to that.
Strange. I utterly fail to see the reason behind that.
The case I could imagine was a SubEnum, that allowed a free
selection of a subset of BaseEnum's instances, and otherwise
behaves like a wrapper based on my own class-wrapper proposal
(messageid [still quoted somewhere above] ).
Wrap, reduce range, or both. Yep.
* Now finally, I add one more idea to the list:
Distinguish between "using" and "implementing" an interface with
respect to accessibility.
The point being to allow to publish an (internal) interface
for return values (cookies), that foreign code may use as type
for variables, but not in "implements"-lists for classes.
There's already a few other ways to do this:

But none of them (including even my WeakHashMap approach)
allow checking at compile time, as the proposed change would.
 
A

Andreas Leitgeb

Hendrik Maryns said:
I do see a good point here, since declaring it protected will prevent
people (that are not in a subclass) from trying to invoke it, which the
compiler allows, but then barfs at run time.
That has already been corrected by Lew.
And also because from time to time, you want to use a
non-default sort order (like reverse, or just on another
field as you usually sort on).

You're entirely right wrt. Comparable. Yet I haven't yet
had a use for a different equality imposed on a class from
outside. Harold already mentioned the IdentityHashMap and
its use. Btw., that class uses: System.identityHashCode()
(that's the one I didn't find before)

I don't think there is any pressing need to make that static
method of System also a final method of Object.
 
A

Andreas Leitgeb

Joshua Cranmer said:
Knowing how enums are implemented, you'd basically have to change nearly
every aspect of implementation. I don't see how you could make this
possible:

public enum SomeEnum {
A { void foo() { "Foo!"; } },
B { void foo() { "Bar!"; } },
C { void foo() { "Ugh!"; } };
abstract void foo();
}

public enum Enum2 extends SomeEnum {
A, B;
}

It would have to work almost, but not exactly like the wrapping
previously described for classes. That way, SomeEnum.A and .B
become also be subclasses (and instances) of Enum2.
That SomeEnum.C would *not* be a subclass (instance) of Enum2
does contradict the proposed wrapper properties, but then again,
it's about enums here, not classes. enums already have all sorts
of special cases, already.

There are more technical problems to solve before this could even
possibly become a feature, like the instances' .value(), if e.g.
not C, but A was omitted. I do think it could be solved.
E.g. SubEnums would not be required to have a continuous range of
values starting with 0. They'd just mask out the instances not
selected. Also, Enum2 couldn't specify anonymous subclasses, of
course, since the instance is already there from BaseEnum.
public enum Enum2 subselects SomeEnum {
A { ... } // no no!
}

I like the idea of subselections, but not for any high price.
Wrapping classes is fine. If it turns out not to be compatible with
subselections, then so be it :-(
 
A

Andreas Leitgeb

Andreas Leitgeb said:
Thanks for explaining. I really didn't know that.

Looking at what "javap -verbose java.lang.Thread.State"
prints out, I now have some doubts:

static {};
Code:
Stack=4, Locals=0, Args_size=0
0: new #33; //class java/lang/Thread$State
3: dup
4: ldc #2; //String NEW
6: iconst_0
7: invokespecial #61; //Method "<init>":(Ljava/lang/String;I)V
10: putstatic #52; //Field NEW:Ljava/lang/Thread$State;
.... (ditto for the other fields)

Whether there exists a hidden class for Thread.State.NEW,
called into existence by the jvm, or not, the actual instance
is being created as Thread$State, not Thread$State$NEW.

Where did you get this information about these subclasses from?
Strange. I utterly fail to see the reason behind that.

Can you give sample code that makes these extra classes visible?
or an URL to the part of the JLS or jvm-spec?
 
J

Joshua Cranmer

Andreas said:
Whether there exists a hidden class for Thread.State.NEW,
called into existence by the jvm, or not, the actual instance
is being created as Thread$State, not Thread$State$NEW.

Where did you get this information about these subclasses from?

enum subclasses are only created if you have enum bodies.

public enum Operation {
PLUS { public int op(int a, int b) { return a + b; } },
MINUS { public int op(int a, int b) { return a - b; } },
TIMES { public int op(int a, int b) { return a * b; } },
DIVIDES { public int op(int a, int b) { return a / b; } };

public abstract int op(int a, int b);
}

You will see an Operation$PLUS, Operation$MINUS, etc.
 
A

Andreas Leitgeb

Harold Yarmouth said:

Implementing an interface is a property that applies
to an instance. A given instance can be queried
about whether it implements a certain interface.

My design for wrapper classes was primarily inspired by the
discussion about typedef, and the wish to extending this trick:
class ShortName extends LongGenericName<With,Lots,Of,Parameters> {}
such, that one could take a LongGenericName<...> instance and
assign it to a ShortName typed variable. For this to work, ShortName
(as a class) has to be restricted somehow. Fortunately those
necessary restrictions did not logically forbid the adding of
new methods, which then led to a new extra usecase of extending
instances of final classes to enjoy new methods. (See the MyString
example in the post whose messageId I gave (a few postings upthread)
for how that could be used.)

Regarding the necessary restrictions for a wrapper class:
An instance is *not* supposed to know whether the
baseclass or the wrapper was used for its creation.
This detail is crucial to the safety of the "upcast"
from baseclass to the wrapper.

If a wrapper-instance did implement an extra interface, then
clearly it would be distinguishable from a baseclass instance
which would not implement it.

Maybe you have a different design in mind. I tend to stick
to mine, until I find one superior to it in all the points I'm
interested in.
That might be a bad idea.

It is strictly necessary for this particular design of mine.
It may not be for any other design.
 
A

Andreas Leitgeb

Harold Yarmouth said:

I understood Mark as agreeing to you on this point. More verbosely:
"Yes, especially during debugging, when single lines are commented
out and in..., then these current errors are a real PITA."

Don't know if this was really Mark's opinion, but it happens
to at least be mine, by the way :)
My observation is that a) -Xmx still exists and b) Java apps tend to
bloat to a fixed and large fraction of their -Xmx regardless of the
incremental garbage collector (now the default, isn't it?). My hope was
for -Xmx to go away (or be able to be set infinite, and perhaps default
that way)

-Xmx cannot be infinite, because it governs the size of some internal
structures. I agree, that there is some need for better tuned GC-
parameter (-Xm*) defaults.
So you need to set some boolean right before the successful-case
return statement that the finally clause looks at ...

You can of course set that variable as the last statement of the
try-block. It's highly unlikely that isOk=true; will ever throw an
exception itself.
Yes, it should probably be final.

I still don't see the advantage of a final Object-method
over an already existing static method of System.

Anything you could do with the former but not with the latter?
 
A

Andreas Leitgeb

Joshua Cranmer said:
public enum Operation {
PLUS { public int op(int a, int b) { return a + b; } },
MINUS { public int op(int a, int b) { return a - b; } },
...
public abstract int op(int a, int b);
}
You will see an Operation$PLUS, Operation$MINUS, etc.

No. I will see an Operation$1, Operation$2, etc.

And these aren't hidden nor magically created, but do
exist as Operation$1.class, Operation$2.class, etc. files.
 
A

Andreas Leitgeb

Harold Yarmouth said:
I wasn't considering messing with that. Rather, considering that an app
might have ways of dealing with low memory after the GC has done its best.

You're right there. An application might e.g. save precious data to
a disk-file and only then drop it, rather than have it just irrecallably
eliminated by the gc through softrefs.

Sun either isn't aware of such situations (unlikely), or it's just too
difficult to implement the right thing (more likely) - involving
problems that we aren't yet aware of.
 
J

Joshua Cranmer

Andreas said:
No. I will see an Operation$1, Operation$2, etc.

And these aren't hidden nor magically created, but do
exist as Operation$1.class, Operation$2.class, etc. files.

Guess I hypothesized wrong on Java's naming scheme for enum subclasses.

This is part of the reason why trying to subclass enums is difficult, if
not impossible: any enum constant with a body becomes its own subclass
of the enum. The finality of the leaf enum class (whether it's an enum
like Thread.State with no subclasses for the constants or something like
my example which does have subclasses) also means that partial migration
compatibility would have to be thrown out the window; considering how
careful Java was to make sure that generics could be partially migrated,
I don't think any proposal which would require full migration to work
would be accepted.

That said, Mr. Yarmouth was incorrect in saying that they were magically
created.
 
M

Mark Thornton

Andreas said:
-Xmx cannot be infinite, because it governs the size of some internal
structures. I agree, that there is some need for better tuned GC-
parameter (-Xm*) defaults.

It is possible to eliminate -Xmx but there is a performance penalty. The
current system reserves contiguous address space for the maximum heap
size on start up. A garbage collector that acquires address space in
chunks as required is possible.

Mark Thornton
 
M

Mark Thornton

Mark said:
This may be true, but I can run many separate Java applications, each
set to use the maximum memory for my system.
Reserving address space requires very little real memory or even virtual
memory (probably no more than a few empty page table entries). I
routinely use -Xmx1000m by default and don't worry about it. A more
serious problem is that some systems have severely fragmented address
space so that the maximum contiguous space can be as little as 800MB. A
GC that did not require contiguous heap could obtain a much larger heap
on such systems as the total free is still large (1300MB or more). Of
course when everyone moves to 64bit systems these considerations will be
history.

Mark Thornton
 
M

Mark Space

Mark said:
serious problem is that some systems have severely fragmented address
space so that the maximum contiguous space can be as little as 800MB. A
GC that did not require contiguous heap could obtain a much larger heap

Ah, ok thanks for the info. This could be valuable debuggint info someday.

Of
course when everyone moves to 64bit systems these considerations will be
history.

People used to say the same thing about 640k....
 
A

Andreas Leitgeb

Harold Yarmouth said:
but be an "implicit cast" of sorts that immediately throws NPE if the
maybenull actually is null. Think of it as having a ClassCastException
for nullability-typesafetiness.

Runtime null checks can be had with reasonably little typing:
// in one utility class:
public static void nn(Object o) { if (o==null) { throw new NullPointerExcepton(); } }
// in the current class:
import static Utilitclasspath.nn;
// on usage:
Integer i=...;
nn(i);

calling just i.toString(); or i.hashCode(); instead of nn(i); saves
the preparation but is slightly longer per case, and has a higher runtime
penalty. Perhaps getClass() is a bit cheaper. I'm too lazy right now to
test it.

PS: I do not use static import much, so I didn't remember the correct
ordering of the keywords and googled it. This led me to
http://java.sun.com/j2se/1.5.0/docs/guide/language/static-import.html
and the very last sentence is:
" Used appropriately, static import can make your program more readable,
" by removing the boilerplate of repetition of class names.
I do like this reasoning (by Sun) very much, and consider it applicable to
more situations than just static imports.
 
H

Harold Yarmouth

Stefan said:
The process for 7.0 seems to be quite advanced now, and decisions
already seems to be made. So, a wishlist might be more
appropriate for 9.0 (with 8.0 being a maintenance release).

* I want the compiler tool and the database of the JDK as a
part of the JRE.

Server VM. And maybe make it default. With the newer GCs it doesn't have
the responsivity problems that it once did that made it a non-starter
for apps that display UI, and it has THROUGHPUT! Anything heavily using
image processing and graphics, or numerical computation, under the hood
benefits tremendously. That casts a wider net than you might think, too.
Games use graphics heavily. File-sharing tools do a lot of number
crunching hashing files. Authoring tools for audio, video, and still
images work with large volumes of data when filters are applied. And so
forth. Server vm basically makes JNI-for-speed obsolete, which is a very
good thing.
 
H

Harold Yarmouth

Andreas said:
Runtime null checks can be had with reasonably little typing:
// in one utility class:
public static void nn(Object o) { if (o==null) { throw new NullPointerExcepton(); } }
// in the current class:
import static Utilitclasspath.nn;
// on usage:
Integer i=...;
nn(i);

That's a method call and a kludge. getClass() is slightly better at
runtime, since the compiler seeing the value unused and knowing the
method has no side effects can reduce it to just the null check and
still preserve semantics. Even then, people reading the code might go
"WTF?".

And it doesn't put it where it really belongs, right in the type system.
 

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,774
Messages
2,569,596
Members
45,133
Latest member
MDACVReview
Top