Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

7.0 wishlist?

16 views
Skip to first unread message

Harold Yarmouth

unread,
Oct 29, 2008, 4:56:14 AM10/29/08
to
There's probably plenty of these floating around already, but here's
bits of mine:

* Sort-of structural typing. Any object can be used where an interface
type is expected if it has the right set of method signatures, whether
or not it "implements" the interface using that keyword. (It still must
to inherit constants defined in the interface, and methodless interfaces
would not get this behavior else everything becomes, among other things,
serializable!)

* Allow extending final classes, subject to the constraint that new
instance fields cannot be defined and none of the final class's methods
can be overriden regardless of whether the method is explicitly "final".
Essentially allows wrapping final classes.

* Add an unsigned byte type.

* Add some way to specify that something should never be null. Perhaps a
! or a * before or after the variable name or type name.

* Allow omitting the names of unused parameters. Common cases would include:
public void ActionPerformed (ActionEvent) {
foo.setVisible(false);
bar.purge();
}

catch (IOException) {
return false;
}

* Constructor type inference. Also allow an alternate constructor
syntax that doesn't repeat the class name, say using * in its place.
So we can avoid some cases of repeating type names, assign
Map<K, V> myMap = new HashMap(), and perhaps also do e.g.
ConcreteType x = new(argument) where ConcreteType has a suitable
public one-argument constructor.

* Disallow public constructors on abstract classes. They are not
callable by any more code than a protected constructor anyway.

* When a type has a one-argument plus() method, + can be used when the
left hand operand is of that type and the right hand operand is of an
argument type for which the former has a one-argument plus() method.
This + binds with the usual precedence for binary + and x + y is
simply an alternate way of saying x.plus(y). Similarly .times and
some others. <= and >= and < and > use compareTo. === and !== get
added and use .equals, and bind with the same precedence as == and !=.
x + y * z is converted by the compiler to the same bytecodes as
x.plus(y.times(z)) and x * y + z to x.times(y).plus(z). += and the
like combine assignment with addition. ++ does .plus(1) and --
.plus(-1). Unary - does .negated() and x - y is x.plus(y.negated()).
For consistency's sake a .plus method is added to String that returns
a concatenation. None of the +=, *= etc. change objects, only
reassigning references; String s; ... s += t is legal and reassigns
the reference s to a new string object. Compiler remains free to
optimize string accumulations to use StringBuilder under the hood,
and programmer remains encouraged to use it explicitly at least in
loops. StringBuilder also gets a .plus method. Both of these take
Object and use its toString if necessary.
In short, a hygienic form of operator overloading.

* Clean up ImageIO and JAI. A lot of the code in these throws various
RuntimeExceptions in response to seeing something it doesn't like in
file or network data. Really, only checked exceptions (and mainly
IOException) should be thrown in response to seeing something you
don't like in externally-obtained data.

* Inverse to the above, get rid of some awkward checked exceptions or
make them RuntimeExceptions. Culprits include NoSuchAlgorithmException
(usually, the algorithm name is hard-coded and so this exception
signals a bug close to where it is thrown, rather than an erroneous
or unexpected condition the program is expected to cope with in
production) and most others where the usual handling by the coder is
to let the exception kill the thread, catch it and throw new
RuntimeException() or Error(), or catch it and do nothing.

* Dead code in a method should be a warning, not an error.

* Hiding a local variable with a nested-scope local variable should be a
warning, not an error.

* Provide a better way to deal with OutOfMemoryError or low memory in
general, as well as a JVM mode in which a program can use as much
memory as it needs, but the VM will also not greedily take everything
the OS will give it. In this, it may maintain a "load factor" similar
to a HashMap for the entire heap, trying to keep it near 75% full, and
a JVM option to tweak this may exist. Higher gives poorer GC
performance but leaves more RAM for the OS; lower gives better GC
performance but uses more memory; no value throws OOME unless the OS
won't give the Java process memory it needs.
Add System.addLowMemoryListener() or similarly. Listeners are notified
if free memory dips below some threshold, running on a temporary
worker thread and perhaps doing things like flush caches.

* Provide a nicer way to deal with resource release. Possibly have a
Releasable interface added, which specifies a dispose() method and
which would be applied to many objects like streams and JFrames
that already have such a method or a similar method. Methods that
get a non-Swing-container Releasable and don't either return it or
use try...finally to dispose it generate a warning. A do() method
in the same interface takes a Runnable and calls the runnable
then disposes the releasable.

* Especially given the above: a shortcut for new Runnable() { public
void run () { ... }}. Let a brace block appearing where an expression
is expected be equivalent to the above, with the contents of the
brace block in place of the ellipsis (...). Then you can do e.g.
SwingUtilities.invokeLater({foo.setVisible(true);});
Also allow this short form to throw checked exceptions, which it
will be assumed the calling code might throw. (So
SwingUtilities.invokeLater({myOutputStream.write("foo");});
would be treated by the compiler as able to throw IOException,
though in fact it would arise in another thread entirely; on
the other hand, using Runnables as custom control blocks like
the Releasable.do() suggested above would result in the
exception being thrown out of do() and into the code that
physically contains the block. Most invocations of runnables
into separate threads are not with ones that throw unhandled checked
exceptions anyway.

* Allow array literals in expressions other than assignment RHS.
Why the devil is foo(1, "string literal", 3) allowed but
foo(1, {array, literal}, 3) is not, even when foo's second
parameter type is Object?
(The above two can be disambiguated: array literals and statement
blocks are syntactically distinguishable, and array literals will
generally be used where the parameter type is an array type or
Object and runnable literals where the parameter type is Runnable.)

* Have array constructors added to the collection classes:
(with the above as well)
new HashSet({2, 3, 5, 7, 11, 13});
new ArrayList({"foo", "bar", "baz", "quux"});
new HashMap({{"key1", "value1"}, {"key2", "value2"}});

* Add java.lang.Pair<K, V>. Make some existing classes Pair
implementations, e.g. Dimension extends Pair<Integer, Integer>,
possibly also Rectangle extends Pair<Dimension, Dimension>,
Map.Entry<K,V> extends Pair<K,V>, etc.
Two-element array literals allowed where Pair is expected and
produce Pair literals.

* [int x]; defines a final box containing an int, an instance of a
Box<T> with T == Integer, which has methods T get() and void set(T).
One can then do e.g.
[JFrame foo = new JFrame()];
...
SwingUtilities.invokeLater({foo.get().setVisible(true);});
given the above runnable-literal suggestion.
Add a : operator that expands to ".get()." and we have:
SwingUtilities.invokeLater({foo:setVisible(true);});
Almost a closure, there!
The : operator also lets us use WeakReference and the like
more nicely, if we add another touch to handle the case of null.
ref:doSomething()?System.out.println("something was null!");, say.

* In many more cases it might be useful to have a shortcut to
if (x == null) value = this else value = that
so how about more generally allowing x.foo?ifNull -- the ? clause
is executed whenever x is null and the method call when it's not.
Or just allow x?expression1:expression2 for non-Booleans testing
for null.

* Another source of boilerplate code is:
Type t;
try {
t = someExpressionThatMayThrow();
} catch (FooException e) {
...
return/continue/break/throw foo/whatever
}
t.doSomething();

where you don't want to doSomething() if the exception got raised,
doSomething() itself may raise the same exception but it shouldn't be
caught in the same catch, or similarly.
Let an alternate form be:
try {
Type t = someExpressionThatMayThrow();
} continue {
t.doSomething();
} catch (FooException e) {
...
}
which is not shorter, but doesn't break up t's declaration and
assignment. This, among other things, lets t be final, and also
lets the catch fall through without "t may not be assigned!". In
some cases it may save lots of boilerplate code:
Type t = null;
try {
t = someExpressionThatMayThrow();
} catch (FooException e) {
fooNotifier.logError(e.getMessage());
failed = true;
}
if (t != null) {
t.doSomething();
}
Yuck! This occurs a lot in I/O code though, usually with Type
actually InputStream or one of its close relatives. Often we
want to handle failure to open the stream specially versus
a failure once we already have the stream open, though both
throw IOException. Sometimes, for instance, we want to flag
an error in some way if the open fails, but let the IOException
bubble up to the caller if the subsequent I/O fails, as the
latter is "more exceptional" than the former.
The key to the above is to have t remain in scope in the
"continue" block.
(Other ugliness this might relieve includes some cases of nested try
blocks.)

* Full closures. Let anonymous inner classes access nonfinal local
variables of the enclosing scope, by having the compiler put all
such variables used by such inner classes transparently into an
Object[] array rather than directly on the stack, or something of
the sort. (The syntax of using them wouldn't change; only how they
got stored, so they had mutable references on the heap, and thus also
the bytecode generated where they were accessed. The compiler would
also not need to generate type checks when dereferencing this array,
as there'd be no way of getting at it directly in user code.)
Furthermore, let {code} used as an expression rather than a statement
stand for new Object() { public Type1 run(Type2 arg1, Type3 arg2...)
{ code }}. Add "it implements the interface if it is method-compatible
with it" from high up on this list and this gets you Runnable literals
in the void return, no arguments case. Types inferred by what the
expression's type needs to be to fit -- there would need to be a new
type in the system for type-tuples, which would also be useful for
reifying generics and where the <void> tuple represents Runnable,
<void, int> an interface specifying void run (int x), and so on.
Lastly, closures could use "return return x" to throw a
ClosureNonLocalReturnException wrapping an x, and passing a closure
to a method would implicitly wrap the method call in try { ... }
catch (ClosureNonLocalReturnException e) { return e.getWrapped(); }
-- implementing non-local returns. (If the closure "escaped" its
context and then non-local returned, it would manifest in a
RuntimeException: the uncaught ClosureNonLocalReturnException.
The JIT compiler could optimize the generation of nonlocal returns
that proved to be always implicitly caught by eliding generation of
their stack traces. (In practise, each nonlocal return would have
to throw a new anonymous subclass of that exception -- each time
a method was invoked that contained such closures it would cause
the generation of a new anonymous subclass and that class would
be caught by the implicit catch blocks in that invocation of that
method. This would be the conceptual behavior, anyway. In actuality
the generated bytecodes would probably look like those from an
explicit throw of an exception that takes a wrapped value and
an id integer, plus those from an explicit catch clause resembling
if (e.getID() != id) throw e; return e.getWrapped();
The method bytecode would also need to generate this id, and a new
one each call; System.nanoTime() might work on present processors.
An efficient atomic integer incrementor might be needed ultimately,
or an efficient implementation of ThreadLocal, with a bipartite ID
of the thread's identityHashCode and a thread-local incrementing ID.

* Object.identityHashCode().

* Equalizer to go with Comparator, provides equals and hashCode by
proxy, can be used with HashSet and HashMap to provide substitute
key equality and hash functions the way Comparator can provide a
substitute compareTo for TreeSet and TreeMap.

* WeakValueHashMap, LinkedWeakHashMap, and LinkedWeakValueHashMap.
These would all be useful implementing caches where you want the
mapping to go away if the value is no longer in use, but calls
for the value to return the pre-existing object if one existed.
WeakValueHashMap already sort-of exists in one under-the-hood bit
of non-user-reusable Java: the implementation of string interning,
starting whenever they finally got it to GC unused interned strings.
Trying to implement one yourself is a bear, because there's no way
to automatically do something when a reference dies.

* ReferenceQueue.addListener(Reference r) to let you automatically do
something when a reference is enqueued. Or provide a protected method
in Reference that is called when the reference is cleared or is
about to be cleared, so you can e.g. subclass WeakReference, override
this method, and do something specific (such as remove a mapping
from a map).
Closest you can currently get is to use a WeakHashMap of the
same object to
new Object() { protected void finalize() { do.whatever(); }}
and pray.

* Allow subclassing an enum with the subclasses able to REMOVE (not
add!) values. An enum that can be any of X, Y, or Z is a subtype,
rather than a supertype, of one that can be any of X, Y, Z, A, or B
because it is substitutable for the latter but not vice-versa; the
actual created classes would be Super with subclasses Sub, Super.A,
Super.B, Super.X, Super.Y, and Super.Z and subclasses of Sub Sub.X,
Sub.Y, and Sub.Z, with some change to the underlying code to not treat
Sub itself as an enum value for Super and to treat Sub.X, Sub.Y, and
Sub.Z as convertible to their Super counterparts. The former change is
easy: ignore non-leaf subclasses. The latter is also easy, so long as
enum subclasses can't add methods, fields, or similarly.
Might as well also allow creating supertypes, an enum with additional
values that is assignable FROM the original enum but not TO it.
These might be best implemented not as true under-the-hood subclasses
at all, but as parallel types with implicit conversions among them.

Joshua Cranmer

unread,
Oct 29, 2008, 8:07:06 AM10/29/08
to
Harold Yarmouth wrote:
> There's probably plenty of these floating around already, but here's
> bits of mine:
>
> * Sort-of structural typing. Any object can be used where an interface
> type is expected if it has the right set of method signatures, whether
> or not it "implements" the interface using that keyword. (It still must
> to inherit constants defined in the interface, and methodless interfaces
> would not get this behavior else everything becomes, among other things,
> serializable!)

I smell a lot of unexpected bugs coming from this. Note that if you
already have the right method signatures, you could just take the
interface onto the implements list.

> * Allow extending final classes, subject to the constraint that new
> instance fields cannot be defined and none of the final class's methods
> can be overriden regardless of whether the method is explicitly "final".
> Essentially allows wrapping final classes.

No, essentially makes final classes worthless.

> * Add some way to specify that something should never be null. Perhaps a
> ! or a * before or after the variable name or type name.

How about adding a @NotNull annotation and then running your own static
checker?

> * When a type has a one-argument plus() method, + can be used when the
> left hand operand is of that type and the right hand operand is of an
> argument type for which the former has a one-argument plus() method.

[ ... ]

A poor way of doing operator overloading. There are better proposals out
there.

> some others. <= and >= and < and > use compareTo. === and !== get
> added and use .equals, and bind with the same precedence as == and !=.

Except many other languages use == as equivalent to the equals method
and === as equivalent to Java. Also note that you'll fall down with
nulls here.

> * Provide a better way to deal with OutOfMemoryError or low memory in
> general, as well as a JVM mode in which a program can use as much
> memory as it needs, but the VM will also not greedily take everything
> the OS will give it.

Judicious use of WeakReference and SoftReference helps, and there are
also suitable APIs in java.lang.management that already provide much of
this functinoality.

> * Especially given the above: a shortcut for new Runnable() { public
> void run () { ... }}.

[ ... ]

I take it you haven't heard of closures.

> * Allow array literals in expressions other than assignment RHS.
> Why the devil is foo(1, "string literal", 3) allowed but
> foo(1, {array, literal}, 3) is not, even when foo's second
> parameter type is Object?

new Object[] {array, literal} ?

> * Have array constructors added to the collection classes:
> (with the above as well)
> new HashSet({2, 3, 5, 7, 11, 13});
> new ArrayList({"foo", "bar", "baz", "quux"});
> new HashMap({{"key1", "value1"}, {"key2", "value2"}});

new HashSet(Arrays.asList(2, 3, 5, 7, 11, 13));

So much cleaner IMO.

There's also this for the last one:
new HashMap() {{
this.put("key1", "value1");
this.put("key2", "value2");
}};

> * In many more cases it might be useful to have a shortcut to
> if (x == null) value = this else value = that
> so how about more generally allowing x.foo?ifNull -- the ? clause
> is executed whenever x is null and the method call when it's not.
> Or just allow x?expression1:expression2 for non-Booleans testing
> for null.

x == null ? expr1 : expr2 is not at all verbose and much easier to
distinguish on scanning.

> * Full closures.

Someone beat you to this.

> * Allow subclassing an enum with the subclasses able to REMOVE (not
> add!) values.

Very ugly.

Most of your features have little chance of being added since some are
doable in existing syntax anyways, and many of them would require making
deep changes for what I see as little value.

--
Beware of bugs in the above code; I have only proved it correct, not
tried it. -- Donald E. Knuth

Mark Space

unread,
Oct 29, 2008, 12:27:05 PM10/29/08
to
Harold Yarmouth wrote:
> There's probably plenty of these floating around already, but here's

<http://tech.puredanger.com/2008/08/02/java7-prediction-update/>


> * Sort-of structural typing. Any object can be used where an interface
> type is expected if it has the right set of method signatures, whether
> or not it "implements" the interface using that keyword. (It still must

Interesting but not my cuppa. Break down and just type "implements" on
your class please.

> * Allow extending final classes, subject to the constraint that new
> instance fields cannot be defined and none of the final class's methods

Feels yicky. Consider composition instead of inheritance.


> * Add an unsigned byte type.

Probably too late for this, but sure it would have been handy.

>
> * Add some way to specify that something should never be null. Perhaps a
> ! or a * before or after the variable name or type name.

Does this require a runtime check on each assignment? Could be a lot of
overhead...

> * Allow omitting the names of unused parameters. Common cases would
> include:

I agree with Joshua, typo-city.

> * Constructor type inference. Also allow an alternate constructor

Generic methods can do this now. I think it might be handy for Sun to
provide some generic methods to initialize the classes you mention.
Rolling your own for your own classes isn't hard.

> * Disallow public constructors on abstract classes. They are not
> callable by any more code than a protected constructor anyway.

super();?

>
> * When a type has a one-argument plus() method, + can be used when the
> left hand operand is of that type and the right hand operand is of an

OK with me but apparently this ran into technical troubles. Too
complicated for now.

>
> * Clean up ImageIO and JAI. A lot of the code in these throws various
> RuntimeExceptions in response to seeing something it doesn't like in

At least they shouldn't be throwing unsubclassed RuntimeException. Are
they?


> * Inverse to the above, get rid of some awkward checked exceptions or
> make them RuntimeExceptions. Culprits include NoSuchAlgorithmException

Probably also a good idea.

> * Dead code in a method should be a warning, not an error.

Sure, makes debugging hard. Or at least allow a switch to make it a
warning during development.

A good IDE will comeent out dead code in a hurry though...

> * Hiding a local variable with a nested-scope local variable should be a
> warning, not an error.

Dunno about this, just pick a different variable name.

> * Provide a better way to deal with OutOfMemoryError or low memory in

Hmm, I haven't looked at any existing frameworks for using
SoftReferences, but I'd head over to Apache.org and take a look.
Personally I think the garbage collector is probably about as
complicated at Sun can handle at this time.

> the OS will give it. In this, it may maintain a "load factor" similar
> to a HashMap for the entire heap, trying to keep it near 75% full, and

It's been discussed here, at least. I don't know how hard this would
be, but I'm in favor of it, Sun willing. The incremental garbage
collector gets pretty close to this, imo. It slowly prunes out un-used
objects as the program runs, thereby keeping actual memory footprint to
a minimum. Used objects can't be pruned by anyone, of course.

> * Provide a nicer way to deal with resource release. Possibly have a
> Releasable interface added, which specifies a dispose() method and

I think they already have as nice a method as they can. Use finalize()
if you must. Personally I set all my windows to "DISPOSE_ON_CLOSE" so
they just to it for me.


> * Especially given the above: a shortcut for new Runnable() { public
> void run () { ... }}. Let a brace block appearing where an expression

Well... closures may be on their way. Let's hold out for the correct
solution.

> * Allow array literals in expressions other than assignment RHS.

Java arrays need a type, I think, which isn't aways inferable from the
context. Not sure how well this would work in practice.

> * Have array constructors added to the collection classes:

> new HashMap({{"key1", "value1"}, {"key2", "value2"}});

This would be handy, but what type are those arrays?

> * Add java.lang.Pair<K, V>. Make some existing classes Pair

This is so easy to roll your own, I'm sure that's why no one has done it
for you.

> implementations, e.g. Dimension extends Pair<Integer, Integer>,

I think if Sun started messing with these, they'd go the other way.
Dimension is slow. Use the individual X and Y methods instead.

> * [int x]; defines a final box containing an int, an instance of a

> SwingUtilities.invokeLater({foo:setVisible(true);});

Or you could substitute a "." for the ":" and save yourself a lot of
useless code. :rollseyes:

> * In many more cases it might be useful to have a shortcut to
> if (x == null) value = this else value = that

I'm with Joshua, the ternary operator is fine.

> * Another source of boilerplate code is:

> Let an alternate form be:


> try {
> Type t = someExpressionThatMayThrow();
> } continue {
> t.doSomething();
> } catch (FooException e) {
> ...

No opinion. I've written your "yuck" code myself. It's really not that
common though, usually just doing file IO, which can be encapsulated
pretty well.

>
> * Full closures. Let anonymous inner classes access nonfinal local

JSR is done, I think. I'm not really fond of more anonymous classes
though, I wish something more efficient could be used.


> * Object.identityHashCode().

An un-overridable hashcode? I guess, though I wonder if all platforms
can always provide an "identity" for each object. What happens when an
object gets shipped across a network several times? Will it loose it's
identity?


> * Equalizer to go with Comparator, provides equals and hashCode by

A lot of libraries need to change to use this. Sure, if someone is
willing to do the work.

> * WeakValueHashMap, LinkedWeakHashMap, and LinkedWeakValueHashMap.
> These would all be useful implementing caches where you want the

I think the Apache folks may have a framework or three. Didn't actually
check though...

> * ReferenceQueue.addListener(Reference r) to let you automatically do

No opinion.

> * Allow subclassing an enum with the subclasses able to REMOVE (not

Probably going to break a lot of stuff and make enums a lot less
efficient. Please roll your own removable enum.

Andreas Leitgeb

unread,
Oct 29, 2008, 1:00:32 PM10/29/08
to
Harold Yarmouth <hyarmou...@hotmail.com> wrote:
> * Sort-of structural typing. Any object can be used where an interface
> type is expected if it has the right set of method signatures,

There isn't any real distinction between marker interfaces
like Cloneable and "normal" interfaces. As long as
obj instanceof SomeEmptyInterface is not made trivially true
(which of course it shouldn't be under any circumstances)
it's also not possible to make obj instanceof FooInterface
appear to be true, just based on existence of some methods.

And any other type of compatibility inconsistent with the
instanceof-operator is right out of question, anyway.

I don't think this fits into Java.

> * Allow extending final classes, subject to the constraint that new
> instance fields cannot be defined and none of the final class's methods
> can be overriden regardless of whether the method is explicitly "final".
> Essentially allows wrapping final classes.

Yes, yes, yes! Not sure, if you got that idea yourself, or
from reading <slrngfmc5...@gamma.logic.tuwien.ac.at>.
(in case google distorts it: "slrngfmc50.4jb.avl" is the part
before the "at")
As I brought it, it would subsume the functionality
of proposed typedefs plus add some more useful usecases.

> * Add an unsigned byte type.

adding unsigned primitive types of all sizes generally would be
cool, but then Java should also spend some extra effort on sane
semantics:
e.g. any negative value would have to be trivially smaller
than any unsigned value, and an unsigned value beyond the
range of the other signed value would have to be trivially
always larger. That is grossly unlike C's behaviour for
operators with mixed-signedness operands. And that isn't
yet all to it (what sign would be the result of mixed-
signedness addition?)
Complicated as that would become, I doubt it has any chance
of getting into 7.0. I fear the problem about signed byte
is too fubar'ed to be repaired anytime soon.

> * Add some way to specify that something should never be null. Perhaps a
> ! or a * before or after the variable name or type name.

Sounds cool, principially, but I don't like to add a "line noise
character" for that feature, but rather some keyword.
It wouldn't be possible to create arrays of non-null types,
unless there'd also be syntax to pre-initialize the elements.

> * Allow omitting the names of unused parameters. Common cases would include:
> public void ActionPerformed (ActionEvent) {

Really little gain, given that most of the times one really should
do something with the value (especially in catch-blocks), and in
other cases, the name of some parameter gives a hint as to what
is expected there, (and may be used as such by overrides).
Also, for unused method-arguments, the name is usually referred to
by the javadocs. You do javadoc your methods, don't you?

> * Constructor type inference. Also allow an alternate constructor
> syntax that doesn't repeat the class name, say using * in its place.

May be useful in a few special cases, but sends a wrong message in
most other cases:

One shouldn't really use HashMap<...> typed variables in one's
code, but rather Map<...> typed ones for more flexibility lateron
(just assign a TreeMap instance to the Map variable instead of a
HashMap and don't bother with having to change all the variable's
types.)

The proposal would encourage use of:
HashMap<...> hashMap = new *(...);
which would be a bad thing.

(This argument doesn't apply against typdef'ing HashMap to MyTypeMap,
since the alias could still be quite easily changed at one place, if
so needed.)

> * Disallow public constructors on abstract classes. They are not
> callable by any more code than a protected constructor anyway.

Indeed, for abstract classes' constructors: public is equivalent to
protected. So public could be mapped to protected for those. I see
no gain from that mapping, and even much less gain from demanding
programmers to change "public" to "protected". Since they are in
that case equivalent, it means it doesn't really narrow accessibility.
(which otherwise is a generally good thing to do, of course)

> * When a type has a one-argument plus() method, + can be used ...
operator overloading through special method names and signatures.
Quite a controversial topic.

> * Clean up ImageIO and JAI. [w.r.t exceptions]
> * Inverse to the above, get rid of some awkward checked exceptions [...]
No opinion on those

> * Dead code in a method should be a warning, not an error.

agree! It came up already a couple of times in this group.

> * Hiding a local variable with a nested-scope local variable should be a
> warning, not an error.

also agree, but without extra exclamation mark :-)

> * Provide a better way to deal with OutOfMemoryError or low memory in
> general, as well as a JVM mode in which a program can use as much
> memory as it needs, but the VM will also not greedily take everything
> the OS will give it.

long overdue... (i.e.: agree! )

> no value throws OOME unless the OS won't give the Java process memory
> it needs.

It is still good to *be able to* limit a process' memory footprint.
It just shouldn't be limited by default and then also too low (as it is now)
I guess, you meant it that way, too.

> Add System.addLowMemoryListener() or similarly. Listeners are notified
> if free memory dips below some threshold, running on a temporary
> worker thread and perhaps doing things like flush caches.

That's the wrong approach. Rather let the application use
SoftReferences:
<http://java.sun.com/javase/6/docs/api/java/lang/ref/SoftReference.html>

> * Provide a nicer way to deal with resource release.

Hmm, beats me.
I think that this lack of hookability into the GC's actual
results is mostly by design. I do not entirely understand
that design, either. I looked at the implementation of
WeakHashMap, and while it gets the list of Objects on request
(which is done in size(), isEmpty(), and a couple of other
accessor methods), but there indeed is no way to be notified
instantly upon GC (whenever that runs).
I can only guess, that they don't want the little kids to drop
cookie-crumbs *instantly* after having hoovered the room :-)

> * Especially given the above: a shortcut for new Runnable() { public
> void run () { ... }}. Let a brace block appearing where an expression
> is expected be equivalent to the above, with the contents of the
> brace block in place of the ellipsis (...). Then you can do e.g.
> SwingUtilities.invokeLater({foo.setVisible(true);});

That appears to touch the "closures" topic, even though it's
just suggested as syntactic sugar for certain anonymous classes.

> Also allow this short form to throw checked exceptions, which it
> will be assumed the calling code might throw. (So
> SwingUtilities.invokeLater({myOutputStream.write("foo");});
> would be treated by the compiler as able to throw IOException,
> though in fact it would arise in another thread entirely;

There is no sense for "SwingUtilities.invokeLater" to declare to throw
any checked exceptions. Unlike C's "fork", the SwingUtilities.invokeLater
doesn't "return twice": all the created threads don't know nuts about
SwingUtilities.invokeLater. They just exist, and run run() as their
toplevel method.

> on other hand, using Runnables as custom control blocks like


> the Releasable.do() suggested above would result in the
> exception being thrown out of do() and into the code that
> physically contains the block.

This is an entirely different situation, and yes, that one does
make sense. Such a custom block structure would most likely not
take a Runnable, but rather a
"HaroldsRunnable<ThisException,ThatException,...>" :-)

> * Allow array literals in expressions other than assignment RHS.

I think there are a big lot of caveats that need to be dealt
with. It starts, where the Compiler needs to know, just what
is the Element-type. It can infer it in the "assignement-RHS"
case, but not safely elsewhere.

> * Have array constructors added to the collection classes:

If the previous item has a solution, then this one can
easily be done by appending .toList() to the array-literal.
(leaving out the HashMap here, which is a different beast)

> * Add java.lang.Pair<K, V>. Make some existing classes Pair
> implementations, e.g. Dimension extends Pair<Integer, Integer>,
> possibly also Rectangle extends Pair<Dimension, Dimension>,
> Map.Entry<K,V> extends Pair<K,V>, etc.
> Two-element array literals allowed where Pair is expected and
> produce Pair literals.

The Rectangle makes me feel uneasy about it. As a Pair of pairs,
it probably could no longer directly access its own data, but
would have to maintain two pointers to separate Dimension instances.
But then again, I may be wrong...
Is it possible to extend a class with two references, but implement
it all inside the subclass, avoiding even the space wasted for
the inherited fields? I don't think so.

> * [int x]; defines a final box containing an int, an instance of a
> Box<T> with T == Integer, which has methods T get() and void set(T).
> One can then do e.g.
> [JFrame foo = new JFrame()];
> ...
> SwingUtilities.invokeLater({foo.get().setVisible(true);});
> given the above runnable-literal suggestion.
> Add a : operator that expands to ".get()." and we have:
> SwingUtilities.invokeLater({foo:setVisible(true);});
> Almost a closure, there!

But much yuckier syntax ... I don't see the gain at all.

> * In many more cases it might be useful to have a shortcut to
> if (x == null) value = this else value = that
> so how about more generally allowing x.foo?ifNull -- the ? clause
> is executed whenever x is null and the method call when it's not.
> Or just allow x?expression1:expression2 for non-Booleans testing
> for null.

How would this behave with Boolean x= new Boolean(false); ? :-)
The object is not null, but means false (after auto-unboxing).

> * Another source of boilerplate code is:

> try {
> Type t = someExpressionThatMayThrow();
> } continue {
> t.doSomething();
> } catch (FooException e) {
> ...
> }

I saw this discussed also in another language's group.
(using different keywords, but to the same semantics)

I do not see the usecase as all that common, myself.
I wouldn't oppose it, either.

Another entirely different approach could be an
"exemptfromtry { ... }" block inside the try-block.
That would allow for mixing catching and non-catching
blocks inside the try, and thus have all non-exempted
blocks inside the try guarded by the same catch-clauses.
The Compiler would create several ranges to the exception-
table, one for each part between two exemptfromtry's, all
pointing to the same handler-bytecode address.
Just a thought.

> * Full closures.
Quite a controversial topic.

> * Object.identityHashCode().
I could have sworn that I saw some static method of some
utility class that returned the original hashCode for any
instance. Probably some reflection thing. Anyway, wasn't
able to find it now. Even if it doesn't exist, I think
a static method in a reflection-related class would be a
better approach, than adding it to Object.

> * Equalizer to go with Comparator, provides equals and hashCode by
> proxy, can be used with HashSet and HashMap to provide substitute
> key equality and hash functions the way Comparator can provide a
> substitute compareTo for TreeSet and TreeMap.

Never so far found a need for that. Is there any which
using a wrapper for the Key object cannot solve?
Comparator mostly exists because not all classes are
per se Comparable, but all classes are "Equalizable".

> * WeakValueHashMap, LinkedWeakHashMap, and LinkedWeakValueHashMap.
> These would all be useful implementing caches where you want the
> mapping to go away if the value is no longer in use,

So far it looks like WeakHashMap<Key,WeakReference<Value>>
wrapped such as to transparently map the case of a nullified
WeakRef to a "not found" condition.

> WeakValueHashMap already sort-of exists in one under-the-hood bit
> of non-user-reusable Java: the implementation of string interning,
> starting whenever they finally got it to GC unused interned strings.

Maybe they even do it with Soft- or WeakRefs.... Actually I wasn't
really sure, that interned Strings really had a chance of being collected.

> * ReferenceQueue.addListener(Reference r)
Hooking into the GC has come up quite frequently here, and most likely
it's a bad idea in the first place.

> * Allow subclassing an enum with the subclasses able to REMOVE (not
> add!) values. An enum that can be any of X, Y, or Z is a subtype,
> rather than a supertype, of one that can be any of X, Y, Z, A, or B
> because it is substitutable for the latter but not vice-versa;

ok so far.

> actual created classes would be Super with subclasses Sub, Super.A,
> Super.B, Super.X, Super.Y, and Super.Z and subclasses of Sub Sub.X,
> Sub.Y, and Sub.Z, with some change to the underlying code to not treat
> Sub itself as an enum value for Super and to treat Sub.X, Sub.Y, and
> Sub.Z as convertible to their Super counterparts.

I don't get that at all. What Subclasses are you now talking about?
Each instance of a given enum can be really one of an anonymous subclass
of the enum, but needs not. In
enum Foo { X, Y, Z}
There is only one class-file: Foo.class. no Foo$X.class, ...

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 given in my comment to your second item).

E.g.:
enum Base { X, Y, Z { ... }; ... }
enum Sub wrapspartsof Base {
Y,Z;
Sub foo() { return Z; } // ok, implicitly castable to Sub
//Sub bar() { return X; } // would fail: X is not a Sub
//private int count; // would fail: no extra fields allowed.
}
//Base.X.foo(); // fail: no such method.
//Base.Y.foo(); // fail: no such method. (Compiler doesn't know
implicitly, which of Base's possibly countless
wrappers is meant here)
Sub.Y.foo(); // ok, named as Sub.Y, it's of type Sub ...
((Sub)Base.Y).foo(); // ok, Compiler knows compatibility to Sub,
so method foo() is known to be Sub.foo()
Sub.Y.foo(); // ok,
Base.X instanceof Sub // false
Base.Y instanceof Sub // true!
Sub.Y instanceof Sub // trivially true
Sub.Y == Base.Y // true; it's still the same instance afterall.
(all ditto with Z for Y)
Sub sub=...; switch (sub) { case Y: ... case Z: ... } // ok, all cases handled.

* 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.

One use would be for a library to return "handle" objects
from some of its methods, and accept these handles as parameters
to other methods, allowing user-code to do well-defined
tasks on these handles outside the library, but preventing
foreign code from implementing own classes for that interface
(and especially: possibly feeding those back to the library)
There are of course other ways to achieve that, like keeping
a WeakHashMap of valid handles, but that's far less elegant.

Joshua Cranmer

unread,
Oct 29, 2008, 1:57:56 PM10/29/08
to
Harold Yarmouth wrote:
> * Provide a better way to deal with OutOfMemoryError or low memory in
> general, as well as a JVM mode in which a program can use as much
> memory as it needs, but the VM will also not greedily take everything
> the OS will give it. In this, it may maintain a "load factor" similar
> to a HashMap for the entire heap, trying to keep it near 75% full, and
> a JVM option to tweak this may exist. Higher gives poorer GC
> performance but leaves more RAM for the OS; lower gives better GC
> performance but uses more memory; no value throws OOME unless the OS
> won't give the Java process memory it needs.
> Add System.addLowMemoryListener() or similarly. Listeners are notified
> if free memory dips below some threshold, running on a temporary
> worker thread and perhaps doing things like flush caches.

On this topic in specific:

The JVM has years of experience with tuning GC; the JVM's garbage
collector (all 3 of them?) is one of the best out there. One lesson of
the past few decades is that manual memory management is extremely
difficult to get right; a garbage collector which has been worked on for
over a decade is probably going to be managing its resources better than
any custom scheme you come up with for your application.

SoftReferences in particular are means of this: if you hold a
SoftReference to an object, you are telling the garbage collector that
you are willing to give up the reference if memory resources are getting
low. Since it directly interfaces with the garbage collector, it is
likely to be far more performant than listening for low memory and then
flushing caches.

Consider the case where some resource is consuming memory at a fast
rate, e.g., downloading a large image over a fast connection.

Under a SoftReference scheme, as the garbage collector notices that
memory is getting tight, it will start finding and freeing the soft
references when trying to allocate new memory.

Under a listener scheme, these have to happen, in order:
1. The GC will have to notice that memory is getting tight.
2. The GC will have to tell the event dispatcher that memory is tight.
3. The event dispatcher will have to callback the event listeners.
4. The event listeners will have to free the caches.

These are not happening on the same thread; in the right conditions, the
GC will run out of memory before the event listener has the chance to
free it.

The memory usage of the JVM, etc., can be controlled from the command
line with appropriate -X options; I don't know the degree of
specificity, but I'm sure you can at least somewhat control the
aggressiveness of reclaiming memory before requesting from the OS.

In short: I'm sure the people who worked on the JVM GC are much more
knowledgeable in the topic than you or I. Trying to outwit them will
almost definitely result in failure.

Mike Schilling

unread,
Oct 29, 2008, 4:32:43 PM10/29/08
to
Joshua Cranmer wrote:
> Harold Yarmouth wrote:
>> There's probably plenty of these floating around already, but
>> here's
>> bits of mine:
>>
>> * Sort-of structural typing. Any object can be used where an
>> interface type is expected if it has the right set of method
>> signatures, whether or not it "implements" the interface using that
>> keyword. (It still must to inherit constants defined in the
>> interface, and methodless interfaces would not get this behavior
>> else everything becomes, among other things, serializable!)
>
> I smell a lot of unexpected bugs coming from this. Note that if you
> already have the right method signatures, you could just take the
> interface onto the implements list.

I see it as a maintenance nightmare. If methods are added to an
interface, I'd like to be told about it when its implementors fail to
compile, not when code which tries to use some other class as that
interface fails to compile. The may be appropriate for Ruby, but not
for Java.

Mike Schilling

unread,
Oct 29, 2008, 4:33:57 PM10/29/08
to
Andreas Leitgeb wrote:
> Harold Yarmouth <hyarmou...@hotmail.com> wrote:

>> * Allow extending final classes, subject to the constraint that new
>> instance fields cannot be defined and none of the final class's
>> methods
>> can be overriden regardless of whether the method is explicitly
>> "final". Essentially allows wrapping final classes.

And also that the subclass can't call protected members.

Mark Thornton

unread,
Oct 29, 2008, 6:17:19 PM10/29/08
to
Harold Yarmouth wrote:
> * Allow extending final classes, subject to the constraint that new
> instance fields cannot be defined and none of the final class's methods
> can be overriden regardless of whether the method is explicitly "final".
> Essentially allows wrapping final classes.
As you wouldn't be able to override hashCode and equals the contract of
these methods would be broken.

> * Add some way to specify that something should never be null. Perhaps a
> ! or a * before or after the variable name or type name.

An annotation is being proposed to mark parameters etc as non null.

Mark Thornton

Andreas Leitgeb

unread,
Oct 29, 2008, 6:24:24 PM10/29/08
to
Mike Schilling <mscotts...@hotmail.com> wrote:
> Andreas Leitgeb wrote:
>> Harold Yarmouth <hyarmou...@hotmail.com> wrote:
>
>>> * Allow extending final classes, subject to the constraint that new
>>> instance fields cannot be defined and none of the final class's
>>> methods
>>> can be overriden regardless of whether the method is explicitly
>>> "final". Essentially allows wrapping final classes.
> And also that the subclass can't call protected members.

Indeed, except it is in the same package as the wrapped class :-)

Mike Schilling

unread,
Oct 29, 2008, 7:27:55 PM10/29/08
to

Then you'd have the source code for the original class, and could
comment out "final". :-)


Andreas Leitgeb

unread,
Oct 29, 2008, 7:53:35 PM10/29/08
to
Mark Thornton <mtho...@optrak.co.uk> wrote:
> Harold Yarmouth wrote:
>> * Allow extending final classes, subject to the constraint that new
>> instance fields cannot be defined and none of the final class's methods
>> can be overriden regardless of whether the method is explicitly "final".
>> Essentially allows wrapping final classes.
> As you wouldn't be able to override hashCode and equals the contract of
> these methods would be broken.

No it wouldn't. Just because the following things would be
forbidden in such a wrapper class:

* overriding of any methods (overloading still ok)
* implementing any interfaces
* adding non-static fields
* accessing any members of the class, that any other
class in the same package of the wrapper couldn't
also access.

(That should cover all things that could change the
personality of an instance. I.e. things which could
make a baseclass instance be distinguishable from a
wrapper instance, (except for .getClass() and
"instanceof wrapper") if wrapper were a normal subclass
and both instances would be accessed from a baseclass
typed reference.)

The expression (new Wrapper()).getClass() would return
the baseclass!

Wrapper instances are exactly like baseclass instances, so
baseclass instances can be treated like wrapper instances
(and therefore be assigned to wrapper typed references).

If the wrapped baseclass was not final, then you can even
derive from a wrapper class, and that may override all
methods of the wrapper and of the baseclass. That subclasses'
instances are then implicitly castable to the direct wrapper
and to the base class but not backwards. They are even
implicitly castable to other wrappers and wrapper-wrappers
of any class up the hierarchy tree! That's the transitivity
of implicit castability.

Instances of wrappersub would be different from instances
of some plain subclass of baseclass, just like two sibling
classes are per se different.

e.g.: (quoted words are meta names used in for easier referral)
HashMap<K,V> // "baseclass"
class MyTypeMap<T> wraps HashMap<T,MyType> { // "wrapper"
public synchronized MyType getAndSet(T key,MyType val) {
gets and sets...
}
}
class SubMap extends MyTypeMap<Integer> { // "wrappersub"
public MyType getAndSet(Integer key,MyType val) {
do some extra checks
return super.getAndSet(key,val);
}
public MyType put(Integer k, MyType v) {
do some checks
return super.put(k,v);
}
}

Wrappers can also be wrapped, but then neither the methods of
baseclass nor of first wrapper may be overridden in the second
wrapper.

On a different subtopic:

>> * Add some way to specify that something should never be null. Perhaps a
>> ! or a * before or after the variable name or type name.
> An annotation is being proposed to mark parameters etc as non null.

Good news. Lets see how that works out.

Andreas Leitgeb

unread,
Oct 29, 2008, 8:09:15 PM10/29/08
to
Mark Space <mark...@sbcglobal.net> wrote:
>> * Allow extending final classes, subject to the constraint that new
>> instance fields cannot be defined and none of the final class's methods
> Feels yicky. Consider composition instead of inheritance.

The way I proposed it a week or so back, the wrapper's instances
would fulfill the "is a" relation even more strictly than a
subclass' instance does.

>> * Add some way to specify that something should never be null. Perhaps a
>> ! or a * before or after the variable name or type name.
> Does this require a runtime check on each assignment? Could be a lot of
> overhead...

I dislike the proposed syntax, but I'd expect it to work like
generic types: The compiler knows them, and tkes care of them,
such that casting a normal type to a non-null type would only
work by branching away the null case:
e.g. (with yucky syntax)
Integer* nnIntRef=null; // fails to compile
Integer intRef=...; Integer* nnIntRef=intRef; // fails

Integer intRef=...;
Integer* nnIntRef;
if (intRef != null) { nnIntRef=intRef; } // ok.
nnIntRef= (intRef==null)? 42 : intRef; // also ok.
if (intRef == null) break; nnIntRef=intRef; // also ok.
This does require some dataflow analysis by the compiler...

>> * Disallow public constructors on abstract classes. They are not
>> callable by any more code than a protected constructor anyway.
> super();?

That's equally ok with public and with protected, anyway.

lbar...@gmail.com

unread,
Oct 29, 2008, 8:46:37 PM10/29/08
to
I wish they would stop adding features and concentrate on fixing bugs.

Mark Space

unread,
Oct 29, 2008, 9:18:34 PM10/29/08
to
Andreas Leitgeb wrote:

> Integer* nnIntRef=null; // fails to compile
> Integer intRef=...; Integer* nnIntRef=intRef; // fails

> This does require some dataflow analysis by the compiler...

What about:

Map<String,Integer> map = new HashMap<String,Integer>();
nnIntRef = map.get("Blarg");


>
>>> * Disallow public constructors on abstract classes. They are not
>>> callable by any more code than a protected constructor anyway.
>> super();?
> That's equally ok with public and with protected, anyway.
>

Right. I was thinking package-private instead of protected, for some
reason. Carry on.

John W Kennedy

unread,
Oct 29, 2008, 10:39:34 PM10/29/08
to
16-bit and 128-bit binary float.
32-bit, 64-bit, and 128-bit decimal float.


--
John W. Kennedy
"Only an idiot fights a war on two fronts. Only the heir to the
throne of the kingdom of idiots would fight a war on twelve fronts"
-- J. Michael Straczynski. "Babylon 5", "Ceremonies of Light and Dark"

Andreas Leitgeb

unread,
Oct 30, 2008, 2:33:50 AM10/30/08
to
Mark Space <mark...@sbcglobal.net> wrote:
> Andreas Leitgeb wrote:
>> Integer* nnIntRef=null; // fails to compile
>> Integer intRef=...; Integer* nnIntRef=intRef; // fails
>> This does require some dataflow analysis by the compiler...
> Map<String,Integer> map = new HashMap<String,Integer>();
> nnIntRef = map.get("Blarg");

It would fail of course. get returns a normal nullable Integer.
If there were a throwing variant of get(), and if the valuetype was
non-null Integer, then the returntype of that get() would be non-null
integer und thus could be assigned to such a variable. Easy, innit?

Roedy Green

unread,
Oct 30, 2008, 3:53:43 AM10/30/08
to
On Wed, 29 Oct 2008 04:56:14 -0400, Harold Yarmouth
<hyarmou...@hotmail.com> wrote, quoted or indirectly quoted
someone who said :

>* When a type has a one-argument plus() method, + can be used when the
> left hand operand is of that type and the right hand operand is of an
> argument type for which the former has a one-argument plus() method.
> This + binds with the usual precedence for binary + and x + y is
> simply an alternate way of saying x.plus(y


Please NO. How about circle plus or some other additive symbol. You
NEED to know if a plus is primitive or user defined.
--
Roedy Green Canadian Mind Products
http://mindprod.com
A vote for McCain is fearful clinging to McSame.
A vote for Obama is a shot at Obamalot.

Roedy Green

unread,
Oct 30, 2008, 3:53:47 AM10/30/08
to
On Wed, 29 Oct 2008 04:56:14 -0400, Harold Yarmouth
<hyarmou...@hotmail.com> wrote, quoted or indirectly quoted
someone who said :

>


>* Dead code in a method should be a warning, not an error.

similarly a throws in a method that does not throw. It is part of the
signature for future reference or to leave the option open in an
override.

Mike Schilling

unread,
Oct 30, 2008, 4:21:02 AM10/30/08
to
Roedy Green wrote:
> On Wed, 29 Oct 2008 04:56:14 -0400, Harold Yarmouth
> <hyarmou...@hotmail.com> wrote, quoted or indirectly quoted
> someone who said :
>
>>
>> * Dead code in a method should be a warning, not an error.
>
> similarly a throws in a method that does not throw. It is part of
> the
> signature for future reference or to leave the option open in an
> override.

That works fine now.

import java.io.*;

class Throws
{
void method() throws IOException
{
}
}

compiles with no errors (or even warnings) in 1.4. Perhaps you're
thinking of trying to catch an impossible exception, e.g.

import java.io.*;

class Throws
{
void method() throws IOException
{
try
{
int i = 12;
}
catch (IOException ex)
{
}
}
}

This does fail with

Throws.java:11: exception java.io.IOException is never thrown in body
of corresponding try statement
catch (IOException ex)
^
1 error


Harold Yarmouth

unread,
Oct 30, 2008, 4:28:30 AM10/30/08
to
Joshua Cranmer wrote:
> Harold Yarmouth wrote:
>> There's probably plenty of these floating around already, but here's
>> bits of mine:
>>
>> * Sort-of structural typing. Any object can be used where an interface
>> type is expected if it has the right set of method signatures, whether
>> or not it "implements" the interface using that keyword. (It still
>> must to inherit constants defined in the interface, and methodless
>> interfaces would not get this behavior else everything becomes, among
>> other things, serializable!)
>
> I smell a lot of unexpected bugs coming from this.

How so?

> Note that if you already have the right method signatures, you could
> just take the interface onto the implements list.

Not if the class is not under your control for whatever reason.

>> * Allow extending final classes, subject to the constraint that new
>> instance fields cannot be defined and none of the final class's
>> methods can be overriden regardless of whether the method is
>> explicitly "final". Essentially allows wrapping final classes.
>
> No, essentially makes final classes worthless.

Not true. It won't be possible, under that proposal, to break e.g.
String by either changing the behavior for clients working with just
"String", or Integer by e.g. creating a super-bloated subclass that will
gum up the works and get stuck in the intertubes because it's so fat. :-)

I should add that nonpublic fields and methods would not be visible to
the wrapper, unlike what's normally the case. (I mentioned that later in
my post, but it seems to be missing from the above, oddly enough.)

>> * Add some way to specify that something should never be null. Perhaps
>> a ! or a * before or after the variable name or type name.
>
> How about adding a @NotNull annotation and then running your own static
> checker?

Awkward and clunky. More typing than a single punctuation mark, by a
factor of eight -- nearly an order of magnitude. Doesn't "just work"
like existing type-checking, but requires manually linting with some
special tool that you'd first have to find someplace, install, and learn
to use. And so forth.

At minimum it would have to be checked by straight javac, as @Override
is now. But even then, nearly an order of magnitude more typing? This
would be used much more frequently than e.g. @Override, probably on a
large minority of all field, variable, and parameter declarations, if
not an actual majority.

>> * When a type has a one-argument plus() method, + can be used when the
>> left hand operand is of that type and the right hand operand is of an
>> argument type for which the former has a one-argument plus() method.
>
> [ ... ]
>
> A poor way

No, it is not, and I will thank you to stop gratuitously insulting me.
You, sir, have an attitude problem.

If you have nothing pleasant or constructive to say, might I suggest
that you keep your mouth shut in the future?

>> some others. <= and >= and < and > use compareTo. === and !== get
>> added and use .equals, and bind with the same precedence as == and !=.
>
> Except many other languages use == as equivalent to the equals method
> and === as equivalent to Java.

Other languages are irrelevant.

You aren't posting to discuss this, are you? You're just posting to shit
all over it and generally be boorish. Shame on you.

> Also note that you'll fall down with nulls here.

That might require a special case, treating x === y as (x == null)?y ==
null:x.equals(y) than just x.equals(y) perhaps.

All the more reason for collapsing it to just a few characters, if you
ask me.

>> * Provide a better way to deal with OutOfMemoryError or low memory in
>> general, as well as a JVM mode in which a program can use as much
>> memory as it needs, but the VM will also not greedily take everything
>> the OS will give it.
>
> Judicious use of WeakReference and SoftReference helps, and there are
> also suitable APIs in java.lang.management that already provide much of
> this functinoality.

Java.lang.management is not covered by any of the tutorial or similar
documentation that's out there, and is just one package buried in a list
of literally hundreds in the API docs, so you'll forgive me for not
being familiar with it.

>> * Especially given the above: a shortcut for new Runnable() { public
>> void run () { ... }}.
>
> [ ... ]
>
> I take it you haven't heard of closures.

Sure I have. Did you even bother to read my entire post before clicking
"Take A Crap All Over It And Send" in your news reader?

>> * Allow array literals in expressions other than assignment RHS.
>> Why the devil is foo(1, "string literal", 3) allowed but
>> foo(1, {array, literal}, 3) is not, even when foo's second
>> parameter type is Object?
>
> new Object[] {array, literal} ?

Works, but if the array doesn't need to be modifiable, creates a
wasteful duplicate every time.

If you're worried that letting immutable arrays get used in such
contexts could somehow cause problems, keep in mind that this is already
possible:

int[] foo = {1, 2, 3};
...
fooMethod(1, foo, 3);

>> * Have array constructors added to the collection classes:
>> (with the above as well)
>> new HashSet({2, 3, 5, 7, 11, 13});
>> new ArrayList({"foo", "bar", "baz", "quux"});
>> new HashMap({{"key1", "value1"}, {"key2", "value2"}});
>
> new HashSet(Arrays.asList(2, 3, 5, 7, 11, 13));
>
> So much cleaner IMO.

You're joking, right? It makes an unnecessary temporary collection. In
fact, all the collections really ought to have constructors that take an
Iterable and just iterate over it. In many cases, they can be
implemented in all of two lines of code:

super();
addAll(iterable);

given that addAll gets broadened to allow any iterable. Or at least

super()
addAll(collection);

> There's also this for the last one:
> new HashMap() {{
> this.put("key1", "value1");
> this.put("key2", "value2");
> }};

Now you're making a whole extra class. How efficient.

>> Or just allow x?expression1:expression2 for non-Booleans testing
>> for null.
>
> x == null ? expr1 : expr2 is not at all verbose and much easier to
> distinguish on scanning.

It's slightly more verbose and no easier to scan for.

>> * Full closures.
>
> Someone beat you to this.

Now you've gone from "nonconstructive" to "just plain bloody-minded".

>> * Allow subclassing an enum with the subclasses able to REMOVE (not
>> add!) values.
>
> Very ugly.

In your humble opinion.

> Most of your features have little chance of being added

In your humble opinion.

> many of them would require making deep changes for what I see as
> little value.

Perhaps you should make an appointment with your optometrist, then. Many
small wins add up to eventually equal some big ones.

Please don't bother to write back until you have something genuinely
constructive and useful to say. Slagging something without suggesting
improvements (or slagging people, at all) is pointless and a waste of
everybody's time.

Harold Yarmouth

unread,
Oct 30, 2008, 4:30:07 AM10/30/08
to
Mike Schilling wrote:
> Joshua Cranmer wrote:
>> Harold Yarmouth wrote:
>>> There's probably plenty of these floating around already, but
>>> here's
>>> bits of mine:
>>>
>>> * Sort-of structural typing. Any object can be used where an
>>> interface type is expected if it has the right set of method
>>> signatures, whether or not it "implements" the interface using that
>>> keyword. (It still must to inherit constants defined in the
>>> interface, and methodless interfaces would not get this behavior
>>> else everything becomes, among other things, serializable!)
>> I smell a lot of unexpected bugs coming from this.

I don't.

>> Note that if you already have the right method signatures, you
>> could just take the interface onto the implements list.

Not if you don't have the ability to change that class.

> I see it as a maintenance nightmare. If methods are added to an

> interface...

They shouldn't be, not once it's gotten "into the wild" anyway.

Harold Yarmouth

unread,
Oct 30, 2008, 5:09:21 AM10/30/08
to
Mark Space wrote:
> Harold Yarmouth wrote:
>> There's probably plenty of these floating around already, but here's
>
> <http://tech.puredanger.com/2008/08/02/java7-prediction-update/>
>
>
>> * Sort-of structural typing. Any object can be used where an interface
>> type is expected if it has the right set of method signatures, whether
>> or not it "implements" the interface using that keyword. (It still must
>
> Interesting but not my cuppa. Break down and just type "implements" on
> your class please.

The whole point is that sometimes you have a class that effectively does
implement some interface, except for lacking the actual "implements"
bit, and that you didn't write and don't get to edit. Generally you can
subclass it and slap "implements" on the subclass, but instances might
be getting created by code you don't get to edit that you'd like to
treat as implementing the interface ...

>> * Allow extending final classes, subject to the constraint that new
>> instance fields cannot be defined and none of the final class's methods
>
> Feels yicky. Consider composition instead of inheritance.

Eh, the main use for this would be so you could tack on utility methods
to existing types, if they seemed to belong there more naturally than
somewhere else, and still use the resulting objects where the base type
is expected. Basically an auto-wrapper.

>> * Add an unsigned byte type.
>
> Probably too late for this, but sure it would have been handy.

Too late to change byte itself to unsigned, perhaps, but not to add an
additional type.

>> * Add some way to specify that something should never be null. Perhaps
>> a ! or a * before or after the variable name or type name.
>
> Does this require a runtime check on each assignment? Could be a lot of
> overhead...

My thought was that the compiler would issue warnings if a might-be-null
reference (not either marked never null or found to be non-null by
static analysis, such as f in the else block of if (f == null) { this }
else { that }) was assigned to one marked never null, or errors, with a
cast needed to get rid of the warning or error that would produce NPE at
run-time. No run-time checks added anywhere else.

There'd only be anything different if the left hand side of assignment
(or a formal parameter being assigned) was of the "not supposed to be
null" variety AND what was being assigned was not either "not supposed
to be null" or demonstrably non-null by static analysis.

Error if demonstrably null instead.

If neither, one of three things might be done:
* Error, cast needed.
* Warning, cast can remove.
* Implicit cast.

Getting the NPE when the null first tries to get somewhere it doesn't
belong is valuable, though. I don't know how many hours I've spent
tracking how this null snuck into this ArrayList, that one into that
variable, etc., not to mention how some instance variable or another
managed to avoid being initialized.

>> * Allow omitting the names of unused parameters. Common cases would
>> include:
>
> I agree with Joshua, typo-city.

Eh?

>> * Constructor type inference. Also allow an alternate constructor
>
> Generic methods can do this now.

Methods, but not constructors.

> Rolling your own for your own classes isn't hard.

But we have to use other peoples' classes, including especially Sun's
own, every day.

>> * Disallow public constructors on abstract classes. They are not
>> callable by any more code than a protected constructor anyway.
>
> super();?

Called by a descendant, which can see protected constructors.

>> * When a type has a one-argument plus() method, + can be used when the
>> left hand operand is of that type and the right hand operand is of an
>
> OK with me but apparently this ran into technical troubles.

How so?

>> * Clean up ImageIO and JAI. A lot of the code in these throws various
>> RuntimeExceptions in response to seeing something it doesn't like in
>
> At least they shouldn't be throwing unsubclassed RuntimeException. Are
> they?

Yup -- com.sun.media.imageioimpl.plugins.pnm.PNMImageReader throws
unsubclassed RuntimeException instead of IOException or whatever when
the file format is unfamiliar.

java.lang.RuntimeException: What in the stream isn't a PNM image.
at
com.sun.media.imageioimpl.plugins.pnm.PNMImageReader.readHeader(PNMImageReader.java:187)
at
com.sun.media.imageioimpl.plugins.pnm.PNMImageReader.getWidth(PNMImageReader.java:153)

calling getWidth on a PNMImageReader invoked on a jpeg.

Really, though, unexpected/malformed/wrong/generally bogus input from a
source external to the program should produce checked exceptions.

>> * Dead code in a method should be a warning, not an error.
>
> Sure, makes debugging hard.

How? Warnings are just as visible as errors, whether using NB, Eclipse,
or command-line javac. You know it's there when you see it.

>> * Hiding a local variable with a nested-scope local variable should be a
>> warning, not an error.
>
> Dunno about this, just pick a different variable name.

Well, at least it should be consistent, so either that or hiding a field
should be an error too, at least if the field isn't inherited.

>> * Provide a better way to deal with OutOfMemoryError or low memory in
>
> Hmm, I haven't looked at any existing frameworks for using
> SoftReferences, but I'd head over to Apache.org and take a look.

I'm not presently in the market for a web server, but thanks anyway. :-)

> Personally I think the garbage collector is probably about as
> complicated at Sun can handle at this time.

Who said anything about changing the GC? I was thinking more along the
lines of the allocator, and having a listener API for memory-running-low.

>> the OS will give it. In this, it may maintain a "load factor" similar
>> to a HashMap for the entire heap, trying to keep it near 75% full, and
>
> It's been discussed here, at least. I don't know how hard this would
> be, but I'm in favor of it, Sun willing. The incremental garbage
> collector gets pretty close to this, imo. It slowly prunes out un-used
> objects as the program runs, thereby keeping actual memory footprint to
> a minimum.

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) and the process size to tend to hang around a fixed multiple
(say, 4/3) of the actual amount of memory taken up by live objects
(since gc is more efficient if there's some slack space, similar to
hashtables being more efficient with some slack space).

> I think they already have as nice a method as they can. Use finalize()
> if you must. Personally I set all my windows to "DISPOSE_ON_CLOSE" so
> they just to it for me.

I/O is the area where this tends to get the messiest. There really
should be a shortcut to the effect of

foo = whatever();
try {
do something
} finally {
foo.release();
}

Especially awkward is the situation where you want to actually return
the open resource after doing something with it. If you just use
try/finally your return will go through the finally and the stream will
close or whatever that you intended to return open. So you need to set
some boolean right before the successful-case return statement that the
finally clause looks at ...

One thing that might help there would be a deferred return syntax:

return = expression;
...
return;

with the former performing an assignment to a special sort of local
variable and the latter returning it. The idea being that if the return
type was a Releasable, the method might implicitly release anything
assigned to "return" but not actually returned, because of reassignment
(say of null) or an exception throw. Reassignment would release the
resource and an exception throw leaving the method would release the
resource referenced by "return" that isn't actually going to get returned.

Plus, say, the using or with block:

with (InputStream in = new FileInputStream(file)) {
actions
}

is three lines of boilerplate shorter than the try/finally above.

Three lines of boilerplate that get written thousands of times over a
Java programmer's career, mind. So it adds up.

>> * Allow array literals in expressions other than assignment RHS.
>
> Java arrays need a type, I think, which isn't aways inferable from the
> context. Not sure how well this would work in practice.

Tightest bound on a common supertype of the arguments, obviously.

>> * Have array constructors added to the collection classes:
>> new HashMap({{"key1", "value1"}, {"key2", "value2"}});
>
> This would be handy, but what type are those arrays?
>
>> * Add java.lang.Pair<K, V>. Make some existing classes Pair
>
> This is so easy to roll your own, I'm sure that's why no one has done it
> for you.

Except that putting it in the base library code and giving the compiler
special knowledge of it would allow for pair literals, which makes the
arrays above able to work type-safely with the map's generic type
parameters; and it could be employed elsewhere to clean up parts of the
core API.

>> implementations, e.g. Dimension extends Pair<Integer, Integer>,
>
> I think if Sun started messing with these, they'd go the other way.
> Dimension is slow. Use the individual X and Y methods instead.

Dimension is raw field access. With JIT it should be as fast as anything
else.

>> * [int x]; defines a final box containing an int, an instance of a
>
>> SwingUtilities.invokeLater({foo:setVisible(true);});
>
> Or you could substitute a "." for the ":" and save yourself a lot of
> useless code.

The point was to get it into the anonymous inner class in a mutable
form, by shortcutting what you can already do, which is use a
one-element array instead of a straight reference. (What was that old
saw about adding one more layer of indirection?)

> I'm with Joshua, the ternary operator is fine.

At least shorten it to allow x?foo:bar :P

> No opinion. I've written your "yuck" code myself. It's really not that
> common though, usually just doing file IO, which can be encapsulated
> pretty well.

Begging your pardon, but that's like putting nuclear waste in lead-lined
casks and burying them instead of avoiding producing the nuclear waste
to begin with. :-)

> JSR is done, I think. I'm not really fond of more anonymous classes
> though, I wish something more efficient could be used.

More efficient in what sense -- typing/source code bloat, not creating
lots of extra little full-blown classes, run-time memory use, or
run-time speed? Or some combination of these?

>> * Object.identityHashCode().
>
> An un-overridable hashcode?

Yes, it should probably be final.

> I guess, though I wonder if all platforms can always provide an
> "identity" for each object.

It would just return Object.hashCode() -- that is, the return value
hashCode() either does have or else would have if it weren't overridden
anywhere in the ancestry.

> What happens when an object gets shipped across a network several
> times? Will it loose it's identity?

Object hashes are already not guaranteed to be the same in different
sessions or on different JVMs, save for some whose formulas are
specified somewhere (String's, perhaps).

>> * WeakValueHashMap, LinkedWeakHashMap, and LinkedWeakValueHashMap.
>> These would all be useful implementing caches where you want the
>
> I think the Apache folks may have a framework or three. Didn't actually
> check though...

These deserve to be in java.util. Third-party stuff sees less use, since
users don't a) discover they exist as easily, b) have as easy a time
using them (they need to be found, then downloaded separately, and then
their Javadocs don't integrate well with Sun's, either not doing so at
all or going to Sun's website instead of your local copy and therefore
not working if you're offline, also eventually not pointing to the
current version anymore), or c) have as easy a time packaging up their
app after using them (and then the jar equivalent of DLL Hell may be
inflicted upon their users).

Plus, nobody goes looking for third party collection classes. They go
looking for third-party math libraries, web app frameworks, other
domain-specific libraries, and ImageIO plugins and the like.

>> * Allow subclassing an enum with the subclasses able to REMOVE (not
>
> Probably going to break a lot of stuff and make enums a lot less
> efficient.

I specifically determined how to avoid doing so, which discussion you
didn't bother to quote one word of. :P

Harold Yarmouth

unread,
Oct 30, 2008, 5:19:21 AM10/30/08
to

My preference is for the maybenull-to-nonnull assignment to be allowed,
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.

Then nnIntRef = map.get("Blarg"); is perfectly legal, but throws NPE if
the map is missing that key (or has associated it with null). If the map
should definitely have that key, and it is a runtime error for it to
lack it, that expression being that short and succinct but throwing an
exception is exactly the desired situation. (If it's not a runtime error
for the map to lack the key, you use a normal reference instead of a
nonnull one.)

Perhaps also useful would be to let the exception be overridden:

Integer* nnIntRef (NoSuchElementException);
...


nnIntRef = map.get("Blarg");

then has the effect of

Integer intRef;
...
intRef = map.get("Blarg");
if (intRef == null) throw new NoSuchElementException();

If the exception is checked, of course, the assignment needs to be in a
try/catch or the method it's in declared to throw the exception.

Harold Yarmouth

unread,
Oct 30, 2008, 6:18:47 AM10/30/08
to
Andreas Leitgeb wrote:
> Harold Yarmouth <hyarmou...@hotmail.com> wrote:
>> * Sort-of structural typing. Any object can be used where an interface
>> type is expected if it has the right set of method signatures,
>
> There isn't any real distinction between marker interfaces
> like Cloneable and "normal" interfaces.

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

> And any other type of compatibility inconsistent with the
> instanceof-operator is right out of question, anyway.

Of course instanceof would continue to use the same semantics of
not-null-and-is-assignable-to that it currently has. It's just
assignable-to that might be a bit broader.

>> * Allow extending final classes, subject to the constraint that new
>> instance fields cannot be defined and none of the final class's methods
>> can be overriden regardless of whether the method is explicitly "final".
>> Essentially allows wrapping final classes.
>
> Yes, yes, yes! Not sure, if you got that idea yourself, or
> from reading <slrngfmc5...@gamma.logic.tuwien.ac.at>.
> (in case google distorts it: "slrngfmc50.4jb.avl" is the part
> before the "at")

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 I brought it, it would subsume the functionality
> of proposed typedefs plus add some more useful usecases.

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.

> e.g. any negative value would have to be trivially smaller
> than any unsigned value, and an unsigned value beyond the
> range of the other signed value would have to be trivially
> always larger. That is grossly unlike C's behaviour for
> operators with mixed-signedness operands. And that isn't
> yet all to it (what sign would be the result of mixed-
> signedness addition?)

A can of worms best avoided. Make the ubyte type not work with other
integers at all without an explicit cast, or else do the usual Java
thing -- an implicit widening conversion to int and use int's arithmetic.

>> * Add some way to specify that something should never be null. Perhaps a
>> ! or a * before or after the variable name or type name.
>
> Sounds cool, principially, but I don't like to add a "line noise
> character" for that feature, but rather some keyword.

Verbiage alert. This is a slight modifier that would be very common on
reference declarations, so it would be good to economize on typing or
visual clutter where it was used.

> It wouldn't be possible to create arrays of non-null types,
> unless there'd also be syntax to pre-initialize the elements.

String[] array = new String[50];
for (...) { ... populate array ... }
String*[] noNullsArray = array; // Runtime check that no element
// is null gets generated here.
String*[] another = {"Foo", "Bar", "Baz"};

Of course we could get into hairiness with noting whether the array
reference itself can be null:

String*[]* -- which * means which?

Maybe better to use

String[*], String*[*]. The * in brackets then clearly refers to the
array, and the * on String clearly refers to the element type, so the
former is an array reference that cannot be null whose elements can be null.

Arrays are something of a corner case anyway, since they should usually
be avoided in preference to collections, and List<String*>,
List*<String>, etc. are quite unambiguous as to which things cannot be null.

>> * Allow omitting the names of unused parameters. Common cases would include:
>> public void ActionPerformed (ActionEvent) {
> Really little gain, given that most of the times one really should
> do something with the value (especially in catch-blocks), and in
> other cases, the name of some parameter gives a hint as to what
> is expected there, (and may be used as such by overrides).

The cases I was thinking of are e.g.

catch (IOException) {
// Error recovery that is independent of the exact details of
// the exception
}

foo.addActionListener(new ActionListener() {
public void actionPerformed (ActionEvent) {
doIt(); // Independent of the event object, and nobody
// will ever subclass and override this!
}
}

> Also, for unused method-arguments, the name is usually referred to
> by the javadocs. You do javadoc your methods, don't you?

My anonymous inner class actionPerformed methods?

You're joking, right?

:-)

>> * Constructor type inference. Also allow an alternate constructor
>> syntax that doesn't repeat the class name, say using * in its place.
> May be useful in a few special cases, but sends a wrong message

No, it does not.

> One shouldn't really use HashMap<...> typed variables in one's
> code, but rather Map<...> typed ones for more flexibility lateron
> (just assign a TreeMap instance to the Map variable instead of a
> HashMap and don't bother with having to change all the variable's
> types.)

I'm just asking for

Map<Key,Value> map = new HashMap();

without any need to repeat the <Key,Value>, that's all!

> The proposal would encourage use of:
> HashMap<...> hashMap = new *(...);

The really-abbreviated new would of course be used for cases where the
types were the same.

StringBuilder sb = new(10);

foo.addActionListener(new() {
public void actionPerformed (ActionEvent) {
...
}
}

etc.

Obviously, the type in the constructor name is not redundant when it's
not the same type as the reference!

> which would be a bad thing.

If someone is determined to write bad code, they will.

> Indeed, for abstract classes' constructors: public is equivalent to
> protected. So public could be mapped to protected for those. I see
> no gain from that mapping, and even much less gain from demanding
> programmers to change "public" to "protected". Since they are in
> that case equivalent, it means it doesn't really narrow accessibility.
> (which otherwise is a generally good thing to do, of course)

It just seems pointless.

On the flip side, the compiler's not permitting "abstract final" is
silly, since it would be useful for making one of those static-utilities
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.

> It is still good to *be able to* limit a process' memory footprint.
> It just shouldn't be limited by default and then also too low (as it is now)
> I guess, you meant it that way, too.

Yes. -Xmx would still work, but omitting it would result in the Java app
having the same memory limits as native code, whatever those might be
depending on hardware and OS.

But it would have to have some gc/allocator tuning to keep a not too low
and not too large amount of slack space. If heap size much bigger than
live objects, return some to OS; if not much bigger at all do an inc GC,
then grow if need be (and the bigger it gets, or if OS won't let it grow
any more, be more eager to do a full collection); etc.

>> Add System.addLowMemoryListener() or similarly. Listeners are notified
>> if free memory dips below some threshold, running on a temporary
>> worker thread and perhaps doing things like flush caches.
> That's the wrong approach.

Whoa! Why the sudden hostility?

No. Nothing that I have said is wrong.

> Rather let the application use SoftReferences:
> <http://java.sun.com/javase/6/docs/api/java/lang/ref/SoftReference.html>

I'm aware of these (and that they don't seem to work all that well --
they seem to actually behave more or less the same as WeakReferences).

But there are other things possible, too. For example, changes of
algorithm/strategy in parts of the program (e.g. use slower but less
storage-intensive methods to do some key piece of work if memory gets
tight). Lots of those kinds of responses (including "alert the user"!)
are not easily done by using SoftReference but are easily done by using
a listener.

Best to support both approaches, each useful for different things.

>> Also allow this short form to throw checked exceptions, which it
>> will be assumed the calling code might throw. (So
>> SwingUtilities.invokeLater({myOutputStream.write("foo");});
>> would be treated by the compiler as able to throw IOException,
>> though in fact it would arise in another thread entirely;
>
> There is no sense for "SwingUtilities.invokeLater" to declare to throw
> any checked exceptions. Unlike C's "fork", the SwingUtilities.invokeLater
> doesn't "return twice": all the created threads don't know nuts about
> SwingUtilities.invokeLater.

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.

> This is an entirely different situation, and yes, that one does
> make sense. Such a custom block structure would most likely not
> take a Runnable, but rather a
> "HaroldsRunnable<ThisException,ThatException,...>" :-)

Having to declare all kinds of types like that explicitly would be a
pain, though. Having block literals that implicitly have such types
would be much nicer. (The types would still show up explicitly in method
argument declarations when programming to receive such things, though.
But that's hardly avoidable.)

>> * Allow array literals in expressions other than assignment RHS.
> I think there are a big lot of caveats that need to be dealt
> with. It starts, where the Compiler needs to know, just what
> is the Element-type. It can infer it in the "assignement-RHS"
> case, but not safely elsewhere.

Why not just least common denominator? The most specialized type that
still is assignable from all of the types of the element expressions.

>> * Have array constructors added to the collection classes:
> If the previous item has a solution, then this one can
> easily be done by appending .toList() to the array-literal.

Wasteful in the extreme. Not just one intermediate object, but probably
actually N+1, and a whole extra O(N) copy of the collection.

Adding an Iterable-accepting constructor to the non-Map collections
seems ideal.

> The Rectangle makes me feel uneasy about it. As a Pair of pairs,
> it probably could no longer directly access its own data, but
> would have to maintain two pointers to separate Dimension instances.
> But then again, I may be wrong...

The JIT could work its usual magic on ones that were used and discarded
locally.

> But much yuckier syntax ... I don't see the gain at all.

Not versus "real" closures, I'm sure. But it might pay off to think of
ways to sneak them in by the back door, so to speak. :-)

> How would this behave with Boolean x= new Boolean(false); ? :-)
> The object is not null, but means false (after auto-unboxing).

If the object is convertible to boolean, the boolean value is used. If
it's not, it's nullness is used. If it's a non-boolean primitive, it's
an error, or else its zeroness is used. (That last gives more or less
the same semantics found in C and C++, but without having a general
convertibility to boolean in any context, only the ternary operator.)

> Another entirely different approach could be an
> "exemptfromtry { ... }" block inside the try-block.

Oh, my God. Uggg-leee!

>> * Full closures.
> Quite a controversial topic.

Quite.

>> * Object.identityHashCode().
> I could have sworn that I saw some static method of some
> utility class that returned the original hashCode for any
> instance.

Yes, but it really belongs as a final instance method of Object.

> Even if it doesn't exist, I think
> a static method in a reflection-related class would be a
> better approach, than adding it to Object.

Why? Surely not some "adding things to Object is expensive" notion? This
wouldn't add a *field* or anything, after all, and one more method is
just one more entry in one more method table in one place.

In fact the default Object hashCode could then be reimplemented to just
call identityHashCode. There'd hardly even be more bytecode in the
Object class -- only the same amount that results from adding

int foo () {
return bar();
}

to a class.

>> * Equalizer to go with Comparator, provides equals and hashCode by
>> proxy, can be used with HashSet and HashMap to provide substitute
>> key equality and hash functions the way Comparator can provide a
>> substitute compareTo for TreeSet and TreeMap.
> Never so far found a need for that.

Well, I have. Lots of times.

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.

> Is there any which using a wrapper for the Key object cannot solve?

Doing it without awkwardness. If the key has important semantics and is
acted on in other ways, having to extract it and wrap it all over the
place gets annoying very quickly and clutters up the code.

Besides, the exact same argument could be made for never introducing
Comparator (and thus for abolishing it now).

> Comparator mostly exists because not all classes are
> per se Comparable, but all classes are "Equalizable".

There are plenty of cases where also it is useful to have multiple
notions of order-comparison for one type, each such notion used in a
different context. And that right there often implies a different notion
of equality.

> So far it looks like WeakHashMap<Key,WeakReference<Value>>
> wrapped such as to transparently map the case of a nullified
> WeakRef to a "not found" condition.

Maybe you don't want the key to be weak, though? Or don't want the map
to bloat up with dud entry objects. WeakHashMap presumably has some way
of making these go away. It's not easy to see how to implement such a
thing (even subclassing WeakReference and/or ReferenceQueue doesn't open
any new doors) oneself. References must use some VM-hook magic to do
their things, and making map entries that go away when a reference is
cleared likewise seems to require such.

> Maybe they even do it with Soft- or WeakRefs.... Actually I wasn't
> really sure, that interned Strings really had a chance of being collected.

I think they didn't used to be, in older Java versions.

>> * ReferenceQueue.addListener(Reference r)
> Hooking into the GC has come up quite frequently here, and most likely
> it's a bad idea in the first place.

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. ReferenceQueue doesn't expose any public or
protected methods that can be overridden to do the job, unfortunately,
but whoever can edit its private implementation can surely create such,
ergo Sun can, without changing one byte of the VM or GC implementation.

As it is, I think the effect can be achieved by making a Thread that
calls the blocking poll method on the queue and invokes listener
objects. So my proposal boils down to "put such a thing in the standard
API somewhere for everyone to use it without having to reinvent it". :-)

>> actual created classes would be Super with subclasses Sub, Super.A,
>> Super.B, Super.X, Super.Y, and Super.Z and subclasses of Sub Sub.X,
>> Sub.Y, and Sub.Z, with some change to the underlying code to not treat
>> Sub itself as an enum value for Super and to treat Sub.X, Sub.Y, and
>> Sub.Z as convertible to their Super counterparts.
>
> I don't get that at all. What Subclasses are you now talking about?

Referring to the enum implementation, which has the enum constants
actually singleton instances of same-named subclasses.

> Each instance of a given enum can be really one of an anonymous subclass
> of the enum, but needs not. In
> enum Foo { X, Y, Z}
> There is only one class-file: Foo.class. no Foo$X.class, ...

Not on disk, no, but there are four classes in the system at runtime;
some ClassLoader magic sees to that.

There's likewise no MyResourceBundle.class on disk if you have a
PropertiesResourceBundle instead of a ListResourceBundle.

> 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 given in my comment to your second item).

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.
>
> One use would be for a library to return "handle" objects
> from some of its methods, and accept these handles as parameters
> to other methods, allowing user-code to do well-defined
> tasks on these handles outside the library, but preventing
> foreign code from implementing own classes for that interface
> (and especially: possibly feeding those back to the library)
> There are of course other ways to achieve that, like keeping
> a WeakHashMap of valid handles, but that's far less elegant.

There's already a few other ways to do this:

public interface Foo {
void method();
}

public final class Bar () {
private static class RealFoo implements Foo {
public void method () { ... }
void otherMethod () { ... }
}
...
aMethod (Foo foo) {
RealFoo r = (RealFoo)foo;
r.otherMethod();
}
}

This one allows subclassing Foo, but throws ClassCastException if a
foreign Foo subclass is used. No WeakHashMap.


Another, even better, one:

public abstract class Foo {
Foo () {
// Package-private constructor.
if (!getClass().equals(RealFoo.class)) {
throw new IllegalStateException();
}
}
public abstract void method ();
}

This won't let anyone even instantiate a BogoFoo. Even using reflection
tricks, or exploiting the wart that you can't make something truly
package-private (invisible even to its own subclasses outside the package).


And then there's:

public final class Foo {
RealFoo delegate; // Package-private field. No subclassing.
public void method () {
delegate.method();
}
}

public final class Bar () {
private static final class RealFoo {
void method () { ... }
void otherMethod () { ... }
}
...
aMethod (Foo foo) {
foo.delegate.otherMethod();
}
}

which appears to cleanly achieve exactly what you want, save that
"delegate" could be molested using reflection (or, perhaps,
serialization hacks).

Harold Yarmouth

unread,
Oct 30, 2008, 6:19:32 AM10/30/08
to

Maybe you want it to be "final" as far as everyone else is concerned,
though?

Bent C Dalager

unread,
Oct 30, 2008, 6:28:00 AM10/30/08
to

Technically speaking, this is only guaranteed if the package in
question is sealed. I don't think this is the norm.

Cheers,
Bent D
--
Bent Dalager - b...@pvv.org - http://www.pvv.org/~bcd
powered by emacs

Harold Yarmouth

unread,
Oct 30, 2008, 6:28:24 AM10/30/08
to
Joshua Cranmer wrote:
> Harold Yarmouth wrote:
>> * Provide a better way to deal with OutOfMemoryError or low memory in
>> general, as well as a JVM mode in which a program can use as much
>> memory as it needs, but the VM will also not greedily take everything
>> the OS will give it. In this, it may maintain a "load factor" similar
>> to a HashMap for the entire heap, trying to keep it near 75% full, and
>> a JVM option to tweak this may exist. Higher gives poorer GC
>> performance but leaves more RAM for the OS; lower gives better GC
>> performance but uses more memory; no value throws OOME unless the OS
>> won't give the Java process memory it needs.
>> Add System.addLowMemoryListener() or similarly. Listeners are notified
>> if free memory dips below some threshold, running on a temporary
>> worker thread and perhaps doing things like flush caches.
>
> On this topic in specific:
>
> The JVM has years of experience with tuning GC; the JVM's garbage
> collector (all 3 of them?) is one of the best out there. One lesson of
> the past few decades is that manual memory management is extremely
> difficult to get right; a garbage collector which has been worked on for
> over a decade is probably going to be managing its resources better than
> any custom scheme you come up with for your application.

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.

> SoftReferences in particular are means of this

I wasn't considering messing with that, either. Rather, considering that
an app might have ways of dealing with low memory after the GC has done
its best. OTHER THAN flushing some "optional" objects.

Changing algorithm choices, for example, or otherwise gracefully
degrading to use less memory at the cost of speed or other tradeoffs.

Or simply warning the user they should save and close some documents.

> In short: I'm sure the people who worked on the JVM GC are much more
> knowledgeable in the topic than you or I. Trying to outwit them will
> almost definitely result in failure.

On straight allocation matters, perhaps, but apps could take more
"long-range" actions besides freeing some objects Right Now, such as
switching to more memory-conservative but slower algorithms or data
structures for some internal purpose, or even advising the user to save
their work and reduce the number of open documents/whatever.

Another factor would be letting the user get away with trying to open a
too-large file or whatever instead of crashing and trashing all their
OTHER work. There should be some way to firewall OOME from affecting the
wrong things. Perhaps allocations on the event dispatch thread should be
favored, with a small portion of the heap reserved for such -- if
another thread (other than a system thread, mind you) wants to allocate,
but there isn't enough memory without using the forbidden set-aside bit
of heap, that thread gets OOME right there, sparing the EDT and critical
system threads. In practise, this means the SwingWorker charged with
loading the too-big document dies and the rest of the application lives,
instead of it being even money that the OOME b0rks up the EDT or
something else important and the UI goes bonkers, goes inconsistent, or
just plain goes away.

Harold Yarmouth

unread,
Oct 30, 2008, 6:33:44 AM10/30/08
to
Mark Thornton wrote:
> Harold Yarmouth wrote:
>> * Allow extending final classes, subject to the constraint that new
>> instance fields cannot be defined and none of the final class's
>> methods can be overriden regardless of whether the method is
>> explicitly "final". Essentially allows wrapping final classes.
> As you wouldn't be able to override hashCode and equals the contract of
> these methods would be broken.

Only if you changed the equality semantics, which is doubtful since
you're not adding fields.

>> * Add some way to specify that something should never be null. Perhaps
>> a ! or a * before or after the variable name or type name.
> An annotation is being proposed to mark parameters etc as non null.

Ugly, verbose, and might not be checked by stock javac. Yuck.

@Override and the like are tolerable, because unlike @NotNull (or
whatever) they are placed before maybe 1 in every 300 lines of normal
Java code, not 1 in 10 or an even higher proportion.

Method argument lists could really suffer with an annotation-based approach.

Contrast:

String* method (int x, Object* y, String z, List*<String*> w) {

with

@NotNull
String method (int x, @NotNull Object y, String z,
@NotNull List<@NotNull String> w) {

What a difference! The former is much less cluttered and much more
readable. (And would an annotation even be able to be applied to a
generic type parameter?)

Harold Yarmouth

unread,
Oct 30, 2008, 6:38:05 AM10/30/08
to
Andreas Leitgeb wrote:
> Mark Thornton <mtho...@optrak.co.uk> wrote:
>> Harold Yarmouth wrote:
>>> * Allow extending final classes, subject to the constraint that new
>>> instance fields cannot be defined and none of the final class's methods
>>> can be overriden regardless of whether the method is explicitly "final".
>>> Essentially allows wrapping final classes.
>> As you wouldn't be able to override hashCode and equals the contract of
>> these methods would be broken.
>
> No it wouldn't. Just because the following things would be
> forbidden in such a wrapper class:
>
> * overriding of any methods (overloading still ok)
> * implementing any interfaces

Why not?

> (That should cover all things that could change the
> personality of an instance. I.e. things which could
> make a baseclass instance be distinguishable from a
> wrapper instance, (except for .getClass() and
> "instanceof wrapper")

And reflection. (Which arguably getClass() and instanceof are part of.)

> The expression (new Wrapper()).getClass() would return
> the baseclass!

That might be a bad idea.

>>> * Add some way to specify that something should never be null. Perhaps a
>>> ! or a * before or after the variable name or type name.
>> An annotation is being proposed to mark parameters etc as non null.
> Good news. Lets see how that works out.

It sounds awful. Too verbose for how frequently it would ideally be used
in code. Often several times on one line (method declarations, plus any
use of generic types).

Roedy Green

unread,
Oct 30, 2008, 6:41:01 AM10/30/08
to
On Thu, 30 Oct 2008 01:21:02 -0700, "Mike Schilling"
<mscotts...@hotmail.com> wrote, quoted or indirectly quoted
someone who said :

>
>That works fine now.

It might be this is just something IntelliJ lint is picky about, or it
could be the catch as you describe. I have got in the habit of making
throws, throw, catch... match perfectly so I can't remember the
precise problem I used to have.

The problem with what I do now, is that I do a lot of maintenance of
throw, throws, catch at various levels in the hierarchy, which is very
rude in code used by other people. I should give them a stable throws
interface which leaves room for future changes.

I ran into this often writing stub or debug code, then later replacing
it with production code that actually threw the exceptions.

Hendrik Maryns

unread,
Oct 30, 2008, 6:20:06 AM10/30/08
to
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Andreas Leitgeb schreef:


> Harold Yarmouth <hyarmou...@hotmail.com> wrote:
>> * Disallow public constructors on abstract classes. They are not
>> callable by any more code than a protected constructor anyway.

> Indeed, for abstract classes' constructors: public is equivalent to
> protected. So public could be mapped to protected for those. I see
> no gain from that mapping, and even much less gain from demanding
> programmers to change "public" to "protected". Since they are in
> that case equivalent, it means it doesn't really narrow accessibility.
> (which otherwise is a generally good thing to do, of course)

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.

>> * Equalizer to go with Comparator, provides equals and hashCode by
>> proxy, can be used with HashSet and HashMap to provide substitute
>> key equality and hash functions the way Comparator can provide a
>> substitute compareTo for TreeSet and TreeMap.

> Never so far found a need for that. Is there any which


> using a wrapper for the Key object cannot solve?

> Comparator mostly exists because not all classes are
> per se Comparable, but all classes are "Equalizable".

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).

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

iEYEARECAAYFAkkJilYACgkQBGFP0CTku6PyawCaAs7YJNLA3VAL7WMGJreWrJeW
ygcAn3Za2rcWtFMydVu59974gn0lHgTS
=43Jv
-----END PGP SIGNATURE-----

Hendrik Maryns

unread,
Oct 30, 2008, 6:39:48 AM10/30/08
to
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Harold Yarmouth schreef:


> Joshua Cranmer wrote:
>> Harold Yarmouth wrote:
>> A poor way
>
> No, it is not, and I will thank you to stop gratuitously insulting me.
> You, sir, have an attitude problem.
>
> If you have nothing pleasant or constructive to say, might I suggest
> that you keep your mouth shut in the future?

Please keep in mind that telling people what to do on Usenet generally
doesn’t work. If you don’t like what people write, don’t read it, it is
the only way, I am afraid. There are long essays on this topic, which I
will not bother to google up for you :-) Generally, responding to them
is a bad idea, therefore I snipped all other similar comments out below.

>>> * Allow array literals in expressions other than assignment RHS.
>>> Why the devil is foo(1, "string literal", 3) allowed but
>>> foo(1, {array, literal}, 3) is not, even when foo's second
>>> parameter type is Object?
>>
>> new Object[] {array, literal} ?
>
> Works, but if the array doesn't need to be modifiable, creates a
> wasteful duplicate every time.

How so? Isn’t {array, literal} supposed to create one as well? The
method expects an array, after all. Oh, I see, it doesn’t. But even if
it expects an Object, there has to be an Object, so the array needs to
be created.

> If you're worried that letting immutable arrays get used in such
> contexts could somehow cause problems, keep in mind that this is already
> possible:
>
> int[] foo = {1, 2, 3};
> ...
> fooMethod(1, foo, 3);

I don’t get it, foo is mutable.

>>> * Have array constructors added to the collection classes:
>>> (with the above as well)
>>> new HashSet({2, 3, 5, 7, 11, 13});
>>> new ArrayList({"foo", "bar", "baz", "quux"});
>>> new HashMap({{"key1", "value1"}, {"key2", "value2"}});
>>
>> new HashSet(Arrays.asList(2, 3, 5, 7, 11, 13));
>>
>> So much cleaner IMO.
>
> You're joking, right? It makes an unnecessary temporary collection.

True, but ISTR that in Java, creating and abandoning a lot of small
classes if more efficient than clinging to one big class. So I wouldn’t
worry about this small class that gets created here. That’s the GC’s
responsibility.

> In
> fact, all the collections really ought to have constructors that take an
> Iterable and just iterate over it.

That seems like a good suggestion, indeed.

> In many cases, they can be
> implemented in all of two lines of code:
>
> super();
> addAll(iterable);
>
> given that addAll gets broadened to allow any iterable.

Which would be consequential (in the sense of being consequential) on
allowing the constructor to take one.

> Or at least
>
> super()
> addAll(collection);
>
>> There's also this for the last one:
>> new HashMap() {{
>> this.put("key1", "value1");
>> this.put("key2", "value2");
>> }};
>
> Now you're making a whole extra class. How efficient.

How would this be less efficient? You’re creating a HashMap anyway.
Oh, you mean the extra class object. I doubt it will make a difference.

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

iEYEARECAAYFAkkJjvQACgkQBGFP0CTku6M87gCgmHxKuMjdXxTr62YXIQdp8A/4
vDIAoJCGS9RBfmA7BGGDkEIvdS8MdFH+
=sQhw
-----END PGP SIGNATURE-----

Bent C Dalager

unread,
Oct 30, 2008, 7:12:02 AM10/30/08
to
On 2008-10-30, Hendrik Maryns <gtw3...@sneakemail.com> wrote:
>
> Harold Yarmouth schreef:

>> If you're worried that letting immutable arrays get used in such
>> contexts could somehow cause problems, keep in mind that this is already
>> possible:
>>
>> int[] foo = {1, 2, 3};
>> ...
>> fooMethod(1, foo, 3);
>
> I don?t get it, foo is mutable.

In theory, though, a compiler might decide to retain the actual array
object between invocations since its size will always be the same,
it's only the contents that is mutable.

It would have to do a lot of analysis beforehand though, to make sure
no one else has retained a reference from a previous invocation. Seems
a bit dicey overall :-)

Hendrik Maryns

unread,
Oct 30, 2008, 6:52:04 AM10/30/08
to
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Harold Yarmouth schreef:


> Mark Space wrote:
>> Harold Yarmouth wrote:
>>> * Provide a better way to deal with OutOfMemoryError or low memory in
>>
>> Hmm, I haven't looked at any existing frameworks for using
>> SoftReferences, but I'd head over to Apache.org and take a look.
>
> I'm not presently in the market for a web server, but thanks anyway. :-)

I think you don’t understand. He refered to
http://commons.apache.org/collections/, specifically to
http://commons.apache.org/collections/api-release/org/apache/commons/collections/map/ReferenceMap.html.
But note that *the* big disadvantage with Jakarta Commons is no
generics, although finally, there is an effort going on.

>>> * WeakValueHashMap, LinkedWeakHashMap, and LinkedWeakValueHashMap.
>>> These would all be useful implementing caches where you want the
>>
>> I think the Apache folks may have a framework or three. Didn't
>> actually check though...
>
> These deserve to be in java.util.

I tend to agree here, but they have to be cleaned up first. And
generics, of course.

> Plus, nobody goes looking for third party collection classes. They go
> looking for third-party math libraries, web app frameworks, other
> domain-specific libraries, and ImageIO plugins and the like.

Well, they should be. Collection classes are amongst the most difficult
to implement well, IMHO.

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

iEYEARECAAYFAkkJkdQACgkQBGFP0CTku6MDYQCfczXfaee8kE8wyd7zcMKX+A9O
vmMAn3cE3kWv2hxZOCzPZfYzpcscQcvO
=O6ZH
-----END PGP SIGNATURE-----

Hendrik Maryns

unread,
Oct 30, 2008, 7:33:40 AM10/30/08
to
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Harold Yarmouth schreef:


> Andreas Leitgeb wrote:
>> Harold Yarmouth <hyarmou...@hotmail.com> wrote:
>> Also, for unused method-arguments, the name is usually referred to
>> by the javadocs. You do javadoc your methods, don't you?
>
> My anonymous inner class actionPerformed methods?
>
> You're joking, right?

I wouldn’t have been. Ok, Javadoc is unnecessary, but for maintenance
purposes some comment makes sence. Might as well be Javadoc
(Alt-Shift-J generates it in Eclipse, and I can never remember the
shortcut to create a block comment, since I almost never use them).

>> Indeed, for abstract classes' constructors: public is equivalent to
>> protected. So public could be mapped to protected for those. I see
>> no gain from that mapping, and even much less gain from demanding
>> programmers to change "public" to "protected". Since they are in
>> that case equivalent, it means it doesn't really narrow accessibility.
>> (which otherwise is a generally good thing to do, of course)
>

> On the flip side, the compiler's not permitting "abstract final" is
> silly, since it would be useful for making one of those static-utilities
> 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.

You are stretching the intended semantics of ‘abstract’ here. It is
meant to mean: this class should be subclassed to fill in functionality.
It is not intended to mean ‘this class has a constructor which you may
not use’.

>>> * Have array constructors added to the collection classes:
>> If the previous item has a solution, then this one can easily be done
>> by appending .toList() to the array-literal.
>
> Wasteful in the extreme. Not just one intermediate object, but probably
> actually N+1, and a whole extra O(N) copy of the collection.

Mind elaborating how you get these numbers? I don’t find that obvious.

>> Another entirely different approach could be an
>> "exemptfromtry { ... }" block inside the try-block.
>
> Oh, my God. Uggg-leee!

But feels more in line with the current syntax to me. I’ve often felt
the need for this.

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

iEYEARECAAYFAkkJm5MACgkQBGFP0CTku6PK4QCfcCulhrfjFpN+dwX4KlCM+t1f
VCYAoLKnHx2oFZ925/Q7SQIG9vbh1PGB
=J8Vt
-----END PGP SIGNATURE-----

Joshua Cranmer

unread,
Oct 30, 2008, 8:01:29 AM10/30/08
to
Harold Yarmouth wrote:
> Joshua Cranmer wrote:
>> Harold Yarmouth wrote:
>>> There's probably plenty of these floating around already, but here's
>>> bits of mine:
>>>
>>> * Sort-of structural typing. Any object can be used where an
>>> interface type is expected if it has the right set of method
>>> signatures, whether or not it "implements" the interface using that
>>> keyword. (It still must to inherit constants defined in the
>>> interface, and methodless interfaces would not get this behavior else
>>> everything becomes, among other things, serializable!)
>>
>> I smell a lot of unexpected bugs coming from this.
>
> How so?

How many interfaces are there in core Java code alone? With these
change, my class would effectively implement dozens of interfaces that I
didn't know exist and whose contracts I am probably violating.

>>> * When a type has a one-argument plus() method, + can be used when the
>>> left hand operand is of that type and the right hand operand is of an
>>> argument type for which the former has a one-argument plus() method.
>>
>> [ ... ]
>>
>> A poor way
>
> No, it is not, and I will thank you to stop gratuitously insulting me.
> You, sir, have an attitude problem.

Then how do you propose to add such features as LHS-based operations,
like 2 * matrix?

> If you have nothing pleasant or constructive to say, might I suggest
> that you keep your mouth shut in the future?

I'm sorry. I assumed you had been a denizen of this newsgroup for a
while and therefore had seen my copious commentary of operator
overloading in the past year or two (which has come up in at least three
separate threads).

>> Except many other languages use == as equivalent to the equals method
>> and === as equivalent to Java.
>
> Other languages are irrelevant.

They are relevant. What you are proposing would be counterintuitive on
multiple levels:

1. Visually === is "more" (i.e., more stringent) equal than ==. That
implies that === would have to become identity equality while == would
become equals()-based equality.
2. This is a COMPLETE reversal of practically every single dynamic
language on here.

Once again, this has been discussed in more detail quite recently
(within the last month, IIRC), so I'll defer to you look at those
threads in question.

> Sure I have. Did you even bother to read my entire post before clicking
> "Take A Crap All Over It And Send" in your news reader?

I reply to large posts as I read them.

>> new Object[] {array, literal} ?
>
> Works, but if the array doesn't need to be modifiable, creates a
> wasteful duplicate every time.

It's doing the exact something the JVM would be doing anyways. In terms
of bytecode, there's no advantage except dropping some extra typing.
Note that Java looks unlikely to drop extra typing merely for the sake
of extra typing based on historical fact.

> You're joking, right? It makes an unnecessary temporary collection. In
> fact, all the collections really ought to have constructors that take an
> Iterable and just iterate over it. In many cases, they can be
> implemented in all of two lines of code:

This is the first suggestion I've seen that would have a very strong
chance of making it in (although not the first worthwhile one, others
were also worthwhile).

>> There's also this for the last one:
>> new HashMap() {{
>> this.put("key1", "value1");
>> this.put("key2", "value2");
>> }};
>
> Now you're making a whole extra class. How efficient.

Doesn't require any changes to existing libraries, the JLS, and the JVM.

>>> Or just allow x?expression1:expression2 for non-Booleans testing
>>> for null.
>>
>> x == null ? expr1 : expr2 is not at all verbose and much easier to
>> distinguish on scanning.
>
> It's slightly more verbose and no easier to scan for.

It's not something I'll belabor, but most people would probably prefer
the second form merely because it obviates that x is an Object and not a
boolean.

>>> * Full closures.
>>
>> Someone beat you to this.
>
> Now you've gone from "nonconstructive" to "just plain bloody-minded".

I have many problems with closures, and so do many others in this
newsgroup. My (and others') complaints are well-documented on this
newsgroup. I cannot feel any sympathy for you if you did not look to
gauge our reactions to basic

>>> * Allow subclassing an enum with the subclasses able to REMOVE (not
>>> add!) values.
>>
>> Very ugly.
>
> In your humble opinion.

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;
}

since SomeEnum$A, SomeEnum$B, and SomeEnum$C inherit SomeEnum.

--
Beware of bugs in the above code; I have only proved it correct, not
tried it. -- Donald E. Knuth

Lew

unread,
Oct 30, 2008, 8:44:29 AM10/30/08
to
Harold Yarmouth wrote:
>> If you have nothing pleasant or constructive to say, might I suggest
>> that you keep your mouth shut in the future?

Joshua Cranmer wrote:
> I'm sorry. I assumed you had been a denizen of this newsgroup for a
> while and therefore had seen my copious commentary of operator
> overloading in the past year or two (which has come up in at least three
> separate threads).

None of the nasty things Harold says or implies about you are true, Joshua.

--
Lew

Lew

unread,
Oct 30, 2008, 8:49:26 AM10/30/08
to
Hendrik Maryns wrote:
> But note that *the* big disadvantage with Jakarta Commons is no
> generics, although finally, there is an effort going on.

I lost a lot of respect for the Apache Commons projects when the commons-lang
project refused to fix the bug in their 'enums' implementation that relies on
a reference to the 'class' literal initializing the class itself.

This used to work prior to Java 5 due to a bug in the implementation of Java.
When Sun fixed the bug, commons-lang broke under that circumstance. The PTB
of the commons-lang project refuse to fix their bug.

WTF?

--
Lew

Lew

unread,
Oct 30, 2008, 8:52:36 AM10/30/08
to
Sorry about the accidental post - I fumble-fingered it.

Andreas Leitgeb wrote:
>> Yes, yes, yes! Not sure, if you got that idea yourself, or
>> from reading <slrngfmc5...@gamma.logic.tuwien.ac.at>.
>> (in case google distorts it: "slrngfmc50.4jb.avl" is the part
>> before the "at")

Harold Yarmouth wrote:
> Eh -- I don't read using Google, and you don't appear to have posted
> this using Google, so why would Google distort it?

This might or might not have occurred to you, "Harold", but others beside you
read this newsgroup. Some of them use GG. Andreas was being responsible for
that, and advising other readers how to decipher his post. He was not talking
only to you.

--
Lew

Lew

unread,
Oct 30, 2008, 9:13:08 AM10/30/08
to
Andreas Leitgeb schreef:

>> Indeed, for abstract classes' constructors: public is equivalent to
>> protected. So public could be mapped to protected for those. I see
>> no gain from that mapping, and even much less gain from demanding
>> programmers to change "public" to "protected". Since they are in
>> that case equivalent, it means it doesn't really narrow accessibility.
>> (which otherwise is a generally good thing to do, of course)

Hendrik Maryns wrote:
> 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.

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.

--
Lew

Hendrik Maryns

unread,
Oct 30, 2008, 10:32:33 AM10/30/08
to
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Lew schreef:

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-----

Message has been deleted

Mike Schilling

unread,
Oct 30, 2008, 2:24:53 PM10/30/08
to

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.


Andreas Leitgeb

unread,
Oct 30, 2008, 3:22:18 PM10/30/08
to
Mike Schilling <mscotts...@hotmail.com> wrote:
> 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.

Martin Gregorie

unread,
Oct 30, 2008, 6:39:42 PM10/30/08
to
On Thu, 30 Oct 2008 15:38:14 +0000, Stefan Ram wrote:

> Harold Yarmouth <hyarmou...@hotmail.com> writes:
>>There's probably plenty of these floating around already, but here's
>>bits of mine:
>

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.


--
martin@ | Martin Gregorie
gregorie. | Essex, UK
org |

Andreas Leitgeb

unread,
Oct 31, 2008, 5:41:43 AM10/31/08
to
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 <hyarmou...@hotmail.com> wrote:
> 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?

>> from reading <slrngfmc5...@gamma.logic.tuwien.ac.at>.
>> (in case google distorts it: "slrngfmc50.4jb.avl" is the part
>> before the "at")
> 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.

>> As I brought it, it would subsume the functionality
>> of proposed typedefs plus add some more useful usecases.

> 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.

>> Sounds cool, principially, but I don't like to add a "line noise
>> character" for that feature, but rather some keyword.
> 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.

>>> * Allow omitting the names of unused parameters. Common cases would include:
>>> public void ActionPerformed (ActionEvent) {

>> 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[].

>> Another entirely different approach could be an
>> "exemptfromtry { ... }" block inside the try-block.
> 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!).

>> I don't get that at all. What Subclasses are you now talking about?
> 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.

Andreas Leitgeb

unread,
Oct 31, 2008, 5:56:27 AM10/31/08
to
Hendrik Maryns <gtw3...@sneakemail.com> wrote:
> 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.

>> Comparator mostly exists because not all classes are

>> per se Comparable, ...


> 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.

Christian

unread,
Oct 31, 2008, 5:56:49 AM10/31/08
to

I sometimes wish there was a variable size ByteBuffer that grows as
needed...

Andreas Leitgeb

unread,
Oct 31, 2008, 6:48:52 AM10/31/08
to
Joshua Cranmer <Pidg...@verizon.invalid> wrote:
> 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 :-(

Andreas Leitgeb

unread,
Oct 31, 2008, 9:03:25 AM10/31/08
to
Andreas Leitgeb <a...@gamma.logic.tuwien.ac.at> wrote:
>>> I don't get that at all. What Subclasses are you now talking about?
>> 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.

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?

>> 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.

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

Joshua Cranmer

unread,
Oct 31, 2008, 10:39:43 AM10/31/08
to
Andreas Leitgeb wrote:
> 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.

Andreas Leitgeb

unread,
Oct 31, 2008, 12:10:37 PM10/31/08
to
Harold Yarmouth <hyarmou...@hotmail.com> wrote:
> Andreas Leitgeb wrote:
>> Mark Thornton <mtho...@optrak.co.uk> wrote:
>>> Harold Yarmouth wrote:
>>>> * Allow extending final classes, subject to the constraint that new
>>>> instance fields cannot be defined and none of the final class's methods
>>>> can be overriden regardless of whether the method is explicitly "final".
>>>> Essentially allows wrapping final classes.
>>> As you wouldn't be able to override hashCode and equals the contract of
>>> these methods would be broken.
>>
>> No it wouldn't. Just because the following things would be
>> forbidden in such a wrapper class:
>>
>> * overriding of any methods (overloading still ok)
>> * implementing any interfaces
>
> Why not?

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.

>> The expression (new Wrapper()).getClass() would return
>> the baseclass!
> That might be a bad idea.

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

Andreas Leitgeb

unread,
Oct 31, 2008, 1:41:57 PM10/31/08
to
Harold Yarmouth <hyarmou...@hotmail.com> wrote:
> Mark Space wrote:
>>> * Dead code in a method should be a warning, not an error.
>> Sure, makes debugging hard.
> How? ...

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.

>>> * Object.identityHashCode().
>> An un-overridable hashcode?
> 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?

Andreas Leitgeb

unread,
Oct 31, 2008, 1:50:35 PM10/31/08
to
Joshua Cranmer <Pidg...@verizon.invalid> wrote:
> 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.

Andreas Leitgeb

unread,
Oct 31, 2008, 2:06:05 PM10/31/08
to
Harold Yarmouth <hyarmou...@hotmail.com> wrote:
> 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.

Joshua Cranmer

unread,
Oct 31, 2008, 2:24:12 PM10/31/08
to

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.

Patrick May

unread,
Oct 31, 2008, 2:40:01 PM10/31/08
to
Roedy Green <see_w...@mindprod.com.invalid> writes:
> On Wed, 29 Oct 2008 04:56:14 -0400, Harold Yarmouth
> <hyarmou...@hotmail.com> wrote, quoted or indirectly quoted
> someone who said :

>>* When a type has a one-argument plus() method, + can be used when the
>> left hand operand is of that type and the right hand operand is of
>> an argument type for which the former has a one-argument plus()
>> method. This + binds with the usual precedence for binary + and x
>> + y is simply an alternate way of saying x.plus(y
>
> Please NO. How about circle plus or some other additive symbol. You
> NEED to know if a plus is primitive or user defined.

Why?

Sincerely,

Patrick

------------------------------------------------------------------------
S P Engineering, Inc. | Large scale, mission-critical, distributed OO
| systems design and implementation.
p...@spe.com | (C++, Java, Common Lisp, Jini, middleware, SOA)

Mark Thornton

unread,
Oct 31, 2008, 2:48:16 PM10/31/08
to
Andreas Leitgeb wrote:
>> 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.

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

Mark Space

unread,
Oct 31, 2008, 4:06:25 PM10/31/08
to
Mark Thornton wrote:
>
> 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.

This may be true, but I can run many separate Java applications, each
set to use the maximum memory for my system. These seem to have no
trouble all running concurrently. Together they exceed my physical
memory by a large margin, and I think I've tested it beyond the virtual
address space too.

So practically speaking, I haven't had any actual trouble with -Xmx the
way it's implemented right now. YMMV.

Mark Thornton

unread,
Oct 31, 2008, 5:11:30 PM10/31/08
to
Mark Space wrote:
> Mark Thornton wrote:
>>
>> 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.
>
> 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

Mark Space

unread,
Oct 31, 2008, 6:54:07 PM10/31/08
to
Mark Thornton wrote:

> 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....

Andreas Leitgeb

unread,
Nov 1, 2008, 4:38:23 PM11/1/08
to
Harold Yarmouth <hyarmou...@hotmail.com> wrote:
> 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.

Harold Yarmouth

unread,
Nov 2, 2008, 3:57:54 AM11/2/08
to
Stefan Ram wrote:
> Harold Yarmouth <hyarmou...@hotmail.com> writes:
>> 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.

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.

Harold Yarmouth

unread,
Nov 2, 2008, 4:00:50 AM11/2/08
to
Andreas Leitgeb wrote:
> Harold Yarmouth <hyarmou...@hotmail.com> wrote:
>> 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);

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.

Harold Yarmouth

unread,
Nov 2, 2008, 4:04:26 AM11/2/08
to

I'm not asking them to create some sort of auto-persistence that can
swap some data out to disk and back in. Heck, the OS page system should
already do that, and that in turn is an argument for infinite default -Xmx.

I was asking them to provide a callback to let the programmer do
something like that if they wanted to. Automatically saving and closing
the least recently touched open document, for example, is app-specific
behavior that could be done given such a callback. (The app could even
retain the document window appearance as a facade, retaining only a
pixel array, and load the real McCoy back in if the user touched the
document window. It would then not seem to have mysteriously closed
itself, but simply to have been slow to access. And the app can be
smarter than the OS pagefile OR the JVM about what makes a sensible
chunk to swap out.)

Harold Yarmouth

unread,
Nov 2, 2008, 4:12:01 AM11/2/08
to
Andreas Leitgeb wrote:
> Harold Yarmouth <hyarmou...@hotmail.com> wrote:
>> Andreas Leitgeb wrote:
>>> Mark Thornton <mtho...@optrak.co.uk> wrote:
>>>> Harold Yarmouth wrote:
>>>>> * Allow extending final classes, subject to the constraint that new
>>>>> instance fields cannot be defined and none of the final class's methods
>>>>> can be overriden regardless of whether the method is explicitly "final".
>>>>> Essentially allows wrapping final classes.
>>>> As you wouldn't be able to override hashCode and equals the contract of
>>>> these methods would be broken.
>>> No it wouldn't. Just because the following things would be
>>> forbidden in such a wrapper class:
>>>
>>> * overriding of any methods (overloading still ok)
>>> * implementing any interfaces
>> Why not?
>
> Implementing an interface is a property that applies
> to an instance. A given instance can be queried
> about whether it implements a certain interface.

If you wrap a Foo, implementing an interface doesn't alter the wrapper's
semantics when treated as a vanilla Foo, EXCEPT for code that uses
casts, reflection, or instanceof. Code that does so is inherently more
fragile than code that is more type-safe and uses polymorphism. If your
wrapper breaks such code, you'd find out and avoid using it there. If
fragile code with security significance proved subvertible this way, it
would indicate a latent flaw in that code's design that had existed anyway.

> 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.

Upcasting from something that doesn't implement some interface to
something that does is already done and is safe.

I think you're worried that the Foo constructor will use instanceof to
decide if it's a wrapped Foo and then fool around somehow if it is, or
if it isn't, or just generally behave differently. Even then, the upcast
shouldn't do anything to change that later.

That would be a badly coded constructor. People sometimes write bad
code. You can't prevent it without stifling everything.

If you really want instanceof to "behave" when the wrapper is treated as
a Foo, instanceof semantics could be changed:

* For non-wraps, same behavior as now
* For wraps, treats as unwrapped type, EXCEPT when the compile-time type
of the reference is the wrapped type, or an interface it implements that
the unwrapped type doesn't.

The wrapped Foo implementing Bar looks exactly like a Foo to Foo users
it's passed to, and still looks like a Bar to Bar users it's passed to.
It's two-faced, but that's just another form of data-hiding. Similar
uses to private inheritance in C++.

> 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.

See above. Though you might not be comfortable with fiddling with
instanceof's semantics.

Andreas Leitgeb

unread,
Nov 2, 2008, 2:01:38 PM11/2/08
to
Harold Yarmouth <hyarmou...@hotmail.com> wrote:
> Andreas Leitgeb wrote:
>> 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.

Since I wrote that, I noticed a flaw in my design, so
I have to revise some of my statements. Nevertheless
that flaw doesn't have any impact on interfaces.

> Upcasting from something that doesn't implement some interface to
> something that does is already done and is safe.

So far only, if the instance was originally of a class
that implemented the interface.

What I wanted to achieve is, that an instance of some class
could be (safely) casted to any wrapper of that class.

If there was:
class Base implements Foo { ... }
class Wrap1 wraps Base { ... }
class Wrap2 wraps Base implements Bar { ... }
Object o = new Base();
then:
Foo f=(Foo)o;
is simple, because the instance at hand knows it is a "Base"
and as such implements "Foo".

otoh, what does it take to use the instance in "o" as a "Bar"?
At the very least, one would have to inform the object itself,
where to find the missing methods (namely in "Wrap2"). This
particular problem only occurs if we allowed the wrappers to
implement new interfaces.
If we left out the new interface aspect, then the only way to
access the new methods would be by a cast to the particular
wrapper and it would be clear where to find the methods.

> The wrapped Foo implementing Bar looks exactly like a Foo to Foo users
> it's passed to, and still looks like a Bar to Bar users it's passed to.

That's easily said..., but (I think) impossible to make work.

PS:
The design flaw I wrote about deals with wrapping generics.
It's not one that spoils it all, but impairs certain usecases
I had in mind for the feature..

Harold Yarmouth

unread,
Nov 2, 2008, 2:33:44 PM11/2/08
to
Hendrik Maryns wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Harold Yarmouth schreef:
>> Joshua Cranmer wrote:
>>> Harold Yarmouth wrote:
>>> A poor way
>> No, it is not, and I will thank you to stop gratuitously insulting me.
>> You, sir, have an attitude problem.
>>
>> If you have nothing pleasant or constructive to say, might I suggest
>> that you keep your mouth shut in the future?
>
> Please keep in mind that telling people what to do on Usenet generally
> doesn’t work.

Please keep in mind that being rude to me without justification
generally doesn't work.

> How so? Isn’t {array, literal} supposed to create one as well? The
> method expects an array, after all. Oh, I see, it doesn’t. But even if
> it expects an Object, there has to be an Object, so the array needs to
> be created.

In the case that it can be immutable, there could be just the single
instance. As things stand, the only way to achieve that is to slap it in
a static final constant. In many cases this is the best practise anyway,
if the array makes sense to name and make easily changed by programmers.
But in some cases, it really doesn't. For instance if you have an array
of the hex digits used in only one place in your code, it's never going
to change and it's pretty obvious what it is (rather than being a "magic
value") if it occurs as a literal at point-of-use. It's just that
currently it can't really, without using the new syntax that will make a
copy every time.

Of course, some arrays (such as the hex digits) might pop up separately
in various classes. Some sort of "interning" of identical array literals
would also be potentially useful.

>> If you're worried that letting immutable arrays get used in such
>> contexts could somehow cause problems, keep in mind that this is already
>> possible:
>>
>> int[] foo = {1, 2, 3};
>> ...
>> fooMethod(1, foo, 3);
>
> I don’t get it, foo is mutable.

It shouldn't be, since it's a direct reference to a literal (rather than
to "new int[]{1, 2, 3}".

>>> So much cleaner IMO.
>> You're joking, right? It makes an unnecessary temporary collection.
>
> True, but ISTR that in Java, creating and abandoning a lot of small
> classes if more efficient than clinging to one big class.

That's not the issue. The issue is that copying a collection is O(n) and
copying it twice thus can be significantly slower than copying it once
if n gets large enough.

>>> There's also this for the last one:
>>> new HashMap() {{
>>> this.put("key1", "value1");
>>> this.put("key2", "value2");
>>> }};
>> Now you're making a whole extra class. How efficient.
>
> How would this be less efficient? You’re creating a HashMap anyway.
> Oh, you mean the extra class object. I doubt it will make a difference.

It works, but it's crude and has crummy and verbose syntax.

Harold Yarmouth

unread,
Nov 2, 2008, 2:57:40 PM11/2/08
to
Joshua Cranmer wrote:
>> How so?
>
> How many interfaces are there in core Java code alone? With these
> change, my class would effectively implement dozens of interfaces that I
> didn't know exist and whose contracts I am probably violating.

I find that unlikely, since method names and signatures would have to
match "sufficiently well" (same name, contravariant argument types, and
covariant return and throws types).

Even if it did, it would be understood that only by putting "implements
Foo" on a class is its author making any claims about their code
adhering to Foo's contract. People use it as a Bar, if it has Bar's
methods but no "implements Bar", at their own risk.

Just as they make unchecked casts of generic collections at their own
risk right now, and prefer to avoid doing so whenever possible.

>> No, it is not, and I will thank you to stop gratuitously insulting me.
>> You, sir, have an attitude problem.
>

> Then how do you propose to add such features as LHS-based operations,
> like 2 * matrix?

For operations that are ... what is the term? Commutative? It can look
for the "plus" method in the RHS if the LHS lacks it. Alternatively the
programmer has to do matrix * 2 instead -- big whup.

For division and subtraction, it would have to either give up or look
for the RHS to have plus and negated, or times and invert. Then
RHS.negated().plus(LHS), or RHS.invert.times(LHS). Sometimes that might
be inefficient. Sometimes it might even throw exceptions -- 2/matrix
would probably try to invert the matrix, then double every cell. If the
matrix isn't invertible (and it may not even be square) the invert
method will presumably throw something, or return null, which would make
the .times throw NPE.

But we already have math operations capable of throwing
ArithmeticException, so...

> I'm sorry. I assumed you had been a denizen of this newsgroup for a
> while and therefore had seen my copious commentary of operator
> overloading in the past year or two (which has come up in at least three
> separate threads).

A quick Google Groups search should have disabused you of that notion.
:-) Not that it matters. If you've previously expressed distaste here
for operator overloading, that really should not mean that everybody
else has to refrain from discussing the subject here on pain of being
personally insulted by you. We should remain free to discuss what we
please, even topics that you might dislike, so long as they pertain to
Java. Given that you are not in charge or otherwise elevated to some
special status here that gives you the right to set topic rules, anyway,
and I strongly suspect that that is the case.

In simpler language, if you don't like operator overloading being
discussed here, perhaps you should go start up
comp.lang.java.programmer.moderated, with yourself as moderator, and say
"No discussions of operator overloading allowed" in its charter?

>>> Except many other languages use == as equivalent to the equals method
>>> and === as equivalent to Java.
>>
>> Other languages are irrelevant.
>
> They are relevant.

They are irrelevant. We are discussing Java. If languages were not
allowed (by who? nobody has this authority anyway) to be too different
from one another, we'd probably all be sitting here discussing Java 7's
implementation of cons, car, and cdr for Chrissake.

Anyway, if you have a better suggestion, go ahead. = is right out
because changing the assignment operator to say := would break pretty
much every piece of existing code out there.

~= perhaps, for equals()?

>> You're joking, right? It makes an unnecessary temporary collection. In
>> fact, all the collections really ought to have constructors that take
>> an Iterable and just iterate over it. In many cases, they can be
>> implemented in all of two lines of code:
>
> This is the first suggestion I've seen that would have a very strong
> chance of making it in (although not the first worthwhile one, others
> were also worthwhile).

A left-handed compliment, at best.

>>> There's also this for the last one:
>>> new HashMap() {{
>>> this.put("key1", "value1");
>>> this.put("key2", "value2");
>>> }};
>>
>> Now you're making a whole extra class. How efficient.
>

> Doesn't require any changes to existing libraries, the JLS, and the JVM.

But it is awkward and verbose.

>> It's slightly more verbose and no easier to scan for.
>
> It's not something I'll belabor, but most people would probably prefer
> the second form merely because it obviates that x is an Object and not a
> boolean.

Usually that would be apparent from context. Quite often, the very
preceding line will have resembled "x = foo.get("string");".

> I have many problems with closures, and so do many others in this
> newsgroup. My (and others') complaints are well-documented on this
> newsgroup. I cannot feel any sympathy for you if you did not look to
> gauge our reactions to basic

?

Your sentence dead-ends in mid-air.

And once more with emphasis, if you do not like discussions of closures
you're free not to read them. Launching a rant sprinkled with personal
attacks against someone for mentioning them in your presence is not
appropriate, adult behavior.

In a weird way, you remind me of the religious prudes that freak out
over people kissing in public, or over television programming they can
avoid with the click of a button on their remote control.

I didn't look to "gauge your reactions" because I shouldn't have to. I
should be able to expect civility so long as I have been civil myself,
and so long as what I write here is on topic here, even if you disagree
with my opinion.

Unfortunately, apparently I should expect rudeness instead in those
circumstances, not even just from you but from several people here.

Courtesy is dead; long live courtesy.

>> In your humble opinion.


>
> 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;
> }
>

> since SomeEnum$A, SomeEnum$B, and SomeEnum$C inherit SomeEnum.

That has been discussed elsewhere in this thread.

Harold Yarmouth

unread,
Nov 2, 2008, 2:58:32 PM11/2/08
to
Lew wrote:

> Joshua Cranmer wrote:
>> I'm sorry. I assumed you had been a denizen of this newsgroup for a
>> while and therefore had seen my copious commentary of operator
>> overloading in the past year or two (which has come up in at least
>> three separate threads).
>
> None of the nasty things Harold says or implies about you are true, Joshua.

Eh? I haven't said any "nasty things" about Joshua.

Harold Yarmouth

unread,
Nov 2, 2008, 3:04:55 PM11/2/08
to
Andreas Leitgeb wrote:
> 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.

Enum values having numeric values that form a continuous range starting
with 0 is overrated anyway. I rarely if ever use this. I'd suggest not
only letting subset-enums violate this, but letting ordinary enums do so
at the coder's behest, i.e. let them override value to return whatever:

public enum FooFlags {
FLAG_X_WHATEVER {
public int value () { return 0; }
}
FLAG_X_MUMBLE {
public int value () { return 1; }
}
FLAG_Y_WHATNOT {
public int value () { return 2; }
}
FLAG_Y_WHOSIT {
public int value () { return 4; }
}
/**
* <p>The error flag.</p>
*/
FLAG_Y_FIDDLESTICKS {
public int value () { return 8; }
}
}

Clearly especially useful (especially along with EnumSet) for
object-oriented typesafe bitmasks that can easily be converted into
integer ones for export to native code or binary files and that can
easily be converted back again.

Harold Yarmouth

unread,
Nov 2, 2008, 3:07:39 PM11/2/08
to
Hendrik Maryns wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Harold Yarmouth schreef:
>> Mark Space wrote:
>>> Harold Yarmouth wrote:
>>>> * Provide a better way to deal with OutOfMemoryError or low memory in
>>> Hmm, I haven't looked at any existing frameworks for using
>>> SoftReferences, but I'd head over to Apache.org and take a look.
>> I'm not presently in the market for a web server, but thanks anyway. :-)
>
> I think you don’t understand.

I think I'm beginning to find unprovoked personal insults quite
tiresome. If Emily Post ever stumbled across this newsgroup, she'd go
white as a sheet!

>> Plus, nobody goes looking for third party collection classes. They go
>> looking for third-party math libraries, web app frameworks, other
>> domain-specific libraries, and ImageIO plugins and the like.
>
> Well, they should be.

No; the needed gamut of collection classes should be (and mostly already
is) in java.util.

Andreas Leitgeb

unread,
Nov 2, 2008, 3:09:45 PM11/2/08
to
Harold Yarmouth <hyarmou...@hotmail.com> wrote:
> Andreas Leitgeb wrote:
>> 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.
>
> I'm not asking them to create some sort of auto-persistence that can
> swap some data out to disk and back in.

I didn't mean that. I just gave another example of what a user could
do beyond GC's possibilities that he cannot(*) do without some way of
being directly notified of impending shortage of memory.

I could imagine another TrackableReference type that will
just be notified of the GC's wish of its destruction, and at
this point still has all the possibilities of full access to
the object to save precious data, or even to tell the GC:
"no, not this one this time, but nag again next time."

If all the TrackableReferences have refused their deletion and
no further SoftReferences are there to dispose, *then* an OOM
Exception may be thrown.

*: short of busy-looping threads watching some reference queue.

> I was asking them to provide a callback to let the programmer do
> something like that if they wanted to.

Yes, I understood exactly that.

Harold Yarmouth

unread,
Nov 2, 2008, 3:13:10 PM11/2/08
to
Andreas Leitgeb wrote:
> -Xmx cannot be infinite, because it governs the size of some internal
> structures.

Those structures would need to be "growable". They probably already
should be, so large -Xmx with a program that (*this* run, anyway) stays
small won't produce inefficiency.

(Have they been using arrays instead of ArrayList? Naughty, naughty Sun!)

> 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.

I don't think it even can, save maybe VMError, which is a showstopper
anyway, and would signal a bug in the JVM to boot. It certainly
shouldn't throw OOME or any of the usual suspects, since it requires no
memory allocation, or NPE, since reference/primitive assignment can't.

What it is is clunky and verbose, my complaint against several idioms
that might be streamlined or eliminated with various of my suggestions.

>>>> * Object.identityHashCode().
>>> An un-overridable hashcode?
>> 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.

Puts it where it belongs. It's a getter of Object properties, so it
logically belongs in Object as an instance method.

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

Be tidy? :-)

Harold Yarmouth

unread,
Nov 2, 2008, 3:19:21 PM11/2/08
to
Hendrik Maryns wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Harold Yarmouth schreef:
>> Andreas Leitgeb wrote:
>>> Harold Yarmouth <hyarmou...@hotmail.com> wrote:
>>> Also, for unused method-arguments, the name is usually referred to
>>> by the javadocs. You do javadoc your methods, don't you?
>> My anonymous inner class actionPerformed methods?
>>
>> You're joking, right?
>
> I wouldn’t have been. Ok, Javadoc is unnecessary, but for maintenance
> purposes some comment makes sence.

It's generally pretty clear what this does in GUI setup code:

FooButton.addActionListener(new ActionListener() {
public void actionPerformed (ActionEvent e) {
fooAction();
}
}

with

private void fooAction () {
...
}

somewhere else in the class.

>> On the flip side, the compiler's not permitting "abstract final" is
>> silly, since it would be useful for making one of those static-utilities
>> 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.
>
> You are stretching the intended semantics of ‘abstract’ here. It is
> meant to mean: this class should be subclassed to fill in functionality.

It is meant to mean "this class cannot be instantiated". I can't think
of anything in Java much more "abstract" (in the English sense) than a
utilities class with no instances.

>>>> * Have array constructors added to the collection classes:
>>> If the previous item has a solution, then this one can easily be done
>>> by appending .toList() to the array-literal.
>> Wasteful in the extreme. Not just one intermediate object, but probably
>> actually N+1, and a whole extra O(N) copy of the collection.
>
> Mind elaborating how you get these numbers?

Copy array into list, copy list into some other collection, instead of
copy array into some other collection.

>>> Another entirely different approach could be an
>>> "exemptfromtry { ... }" block inside the try-block.
>> Oh, my God. Uggg-leee!
>
> But feels more in line with the current syntax to me.

But uggg-leee!

Harold Yarmouth

unread,
Nov 2, 2008, 3:22:12 PM11/2/08
to
Lew wrote:
> Sorry about the accidental post - I fumble-fingered it.
>
> Andreas Leitgeb wrote:
>>> Yes, yes, yes! Not sure, if you got that idea yourself, or
>>> from reading <slrngfmc5...@gamma.logic.tuwien.ac.at>.
>>> (in case google distorts it: "slrngfmc50.4jb.avl" is the part
>>> before the "at")
>
> Harold Yarmouth wrote:
>> Eh -- I don't read using Google, and you don't appear to have posted
>> this using Google, so why would Google distort it?
>
> This might or might not have occurred to you, "Harold", but others
> beside you read this newsgroup.

Your rude and condescending tone is uncalled-for. There is also no
reason to be putting my first name in quotation marks. I can only
imagine that you mean some personal insult by that, "Lew".

This part:

"Not sure, if you got that idea yourself, or from reading
<slrngfmc5...@gamma.logic.tuwien.ac.at>. (in case google distorts
it: "slrngfmc50.4jb.avl" is the part before the "at")"

is quite clearly addressing me personally, and therefore implying that I
use Google for usenet. I was pointing out that that was false.

> He was not talking only to you.

His phrasing and word choice suggest otherwise, "Lew".

Andreas Leitgeb

unread,
Nov 2, 2008, 3:26:45 PM11/2/08
to
Harold Yarmouth <hyarmou...@hotmail.com> wrote:
> Andreas Leitgeb wrote:
>> E.g. SubEnums would not be required to have a continuous range of
>> values starting with 0.
>
> Enum values having numeric values that form a continuous range starting
> with 0 is overrated anyway. I rarely if ever use this.

It is used internally a lot.
The value() is identical with the index of the instance in
the values() array, and some parts of Java rely on it.

values() must not have nulls in it for Enums, but for new
SubEnums, that might be possible.

Joshua Cranmer

unread,
Nov 2, 2008, 3:37:48 PM11/2/08
to
Harold Yarmouth wrote:

> Lew wrote:
>> None of the nasty things Harold says or implies about you are true,
>> Joshua.
>
> Eh? I haven't said any "nasty things" about Joshua.

Read the archives of c.l.j.p of around 1.5-2 years ago, especially those
posts from someone whose first alias is Twisted. Then you'll understand.

Joshua Cranmer

unread,
Nov 2, 2008, 4:19:45 PM11/2/08
to
Harold Yarmouth wrote:
> Just as they make unchecked casts of generic collections at their own
> risk right now, and prefer to avoid doing so whenever possible.

The primary purpose of unchecked conversions is to facilitate migration
to generics at disparate times.

> For operations that are ... what is the term? Commutative? It can look
> for the "plus" method in the RHS if the LHS lacks it. Alternatively the
> programmer has to do matrix * 2 instead -- big whup.

See
<http://groups.google.com/group/comp.lang.java.programmer/browse_frm/thread/444250a94b1020c6/d1a9b67ddd23f8f9?#d1a9b67ddd23f8f9>
for the start of a thread in which I discussed this particular issue at
length, and why I feel that your response is inadequate. Other postings
on that thread reveal my opinions on operator overloading more clearly.

In particular:
* You cannot assume that any operation is commutative. Even for stuff
like multiplication (matrix multiplication is, in fact,
non-commutative), the LHS could be causing a mutation and therefore need
to be evaluated before the RHS.
* "Inverting" operations is often perilous. Dividing by a matrix is
conceptually equivalent to multiplying by its (pseudo)inverse, but
inversion is one of the worst things one can do where solving a matrix
equation is preferred.

>> I'm sorry. I assumed you had been a denizen of this newsgroup for a
>> while and therefore had seen my copious commentary of operator
>> overloading in the past year or two (which has come up in at least
>> three separate threads).
>
> A quick Google Groups search should have disabused you of that notion.

The main thread on which I discussed this was titled Java 7 Features.
You now have a link to said thread, so I need not repeat the several
dozen posts anymore.

>> They are relevant.
>
> They are irrelevant. We are discussing Java. If languages were not
> allowed (by who? nobody has this authority anyway) to be too different
> from one another, we'd probably all be sitting here discussing Java 7's
> implementation of cons, car, and cdr for Chrissake.

The authority is by the people in charge of the languages--in Java's
case, the JSR expert groups. No language exists in a vacuum; note that
Java's generics feature is roughly based on C++'s templates, at least in
terms of syntax.

LISP is not close to Java (they have completely disparate influence
trees), but something like, say, PHP (which shares a moderate influence
with C, C++, and Java) is closer.

> ~= perhaps, for equals()?

o_O ... that makes no sense in terms of syntax.

> But it is awkward and verbose.

To make it less verbose than my example requires several orthogonal steps:
1. A constructor that takes an array of pair objects.
2. A "neat" way to create pair objects.
3. Reduced verbosity in array creation expressions.

If either of the last two does not happen, the creation will end up
being more verbose.

> Usually that would be apparent from context. Quite often, the very
> preceding line will have resembled "x = foo.get("string");".

In my experience with languages such as C and C++, this does not happen
as often as you think.

>> I have many problems with closures, and so do many others in this
>> newsgroup. My (and others') complaints are well-documented on this
>> newsgroup. I cannot feel any sympathy for you if you did not look to
>> gauge our reactions to basic
>

> Your sentence dead-ends in mid-air.

So it does. I think the original statement was supposed to be something
like this:

"... our reactions to basic proposals before repeating the proposal
without adding anything new to say."

> And once more with emphasis, if you do not like discussions of closures
> you're free not to read them. Launching a rant sprinkled with personal
> attacks against someone for mentioning them in your presence is not
> appropriate, adult behavior.

It's not that I don't like them, it's just that no one bothers to add
anything new, so it's the same bloody stuff being repeated once every
month or so. Operator overloading and closures in particular

> I didn't look to "gauge your reactions" because I shouldn't have to. I
> should be able to expect civility so long as I have been civil myself,
> and so long as what I write here is on topic here, even if you disagree
> with my opinion.

I would expect that someone should avoid repeating points belabored to
death before posting something. It doesn't take much effort to determine
if what you are about to add is something that has been recently
discussed in grand detail.

>> since SomeEnum$A, SomeEnum$B, and SomeEnum$C inherit SomeEnum.
>
> That has been discussed elsewhere in this thread.

Indeed, let us move it thither.

Harold Yarmouth

unread,
Nov 2, 2008, 4:32:06 PM11/2/08
to
Andreas Leitgeb wrote:
> 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.

Two: you're also making a statement that you are implementing an
interface deliberately, by doing so, and thus making some sort of
commitment to observe its contract.

The "auto-implement" is intended mainly for the odd situation where an
existing class you can't edit fits some interface and you're willing to
take responsibility for it if it turns out not to actually adhere to the
contract, and try using it where that interface type is expected.
Perhaps it should require an explicit cast, to make it clear that it's
in the same general category of hack as some other cast-using code and
especially unchecked generics casts.

> How would you judge the *runtime* penalty of checking the existence
> of all necessary methods upon each attempted cast?

Oh, no, that checking would occur only once for each run-time type and
the results would get remembered somehow.

>>> from reading <slrngfmc5...@gamma.logic.tuwien.ac.at>.
>>> (in case google distorts it: "slrngfmc50.4jb.avl" is the part
>>> before the "at")

>> 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.

Then your phrasing was somewhat confused, since that paragraph,

>>> Not sure, if you got that idea yourself, or
>>> from reading <slrngfmc5...@gamma.logic.tuwien.ac.at>.
>>> (in case google distorts it: "slrngfmc50.4jb.avl" is the part

>>> before the "at"),

appears to be addressing me specifically.

> 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.

An admirable goal, though I'm not sure why Google would distort a
message-ID in a non-Google posting.

However, putting "in case google distorts it" in a parenthetical aside
attached to "Not sure if you got that idea yourself, or from foo"
implies that either you are using Google and worried that it will mangle
your outbound post, or that you think the "you" who may have got that
idea himself (i.e. me) is using Google, and neither was the case.

Put it down to slightly confused grammar/word choice somewhere I guess.
If the bit about Google had explicitly had broader address, or had been
elsewhere in the post than right next to "you ... yourself", there would
have been no confusion.

>> 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.

My proposal overloaded the "extends" keyword for this -- it would
subclass a non-final class normally, as now, and wrap a final class. You
appear to want to be able to wrap without subclassing non-final classes.
For that a new syntax would be needed. Perhaps "implements" followed by
a class rather than an interface would do the job without adding new
reserved words to Java?

>>> Sounds cool, principially, but I don't like to add a "line noise
>>> character" for that feature, but rather some keyword.
>> 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.

I don't think this would be an issue with Object* object = foobar; or
Object! object = foobar;, somehow.

If things like that proliferated too much, sure. Or if a yucky enough
closure syntax got decided on, or people abused operator overloading.
But bad code will be written whatever tools are handed out, so the
latter isn't an argument against much of anything, and the former is an
argument against having a yucky closure syntax. Neither is an argument
in favor of a verbose non-null syntax.

> As soon as some keyword or other constant verbiage is used,
> it becomes possible to look it up.

If reference declarations started showing up with the odd asterisk,
bang, or other punctuation mark on it, but never primitive declarations,
people would probably be able to guess what was going on, on the basis
of "what other binary flag might be set on references but not primitives
and would be really useful besides can be/cannot be null?" I assume
there'd also be great fanfare and publicity within Java circles
attendant upon the release of such a long-awaited new feature. Someone
would have to have spent a year living under a rock, then crawled out
from under it and stumbled upon some fairly recent Java code, AND not be
especially intelligent or Java-savvy, to not either know OR manage to
guess what was 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.

You'd have a guarantee that if you assigned the get() to a non-nullable
reference and got NPE it was because of a missing key, and you'd get an
NPE if you tried to put a null into the map with put, instead of this
causing errors later (or even silently failing in the case that get() is
expected to sometimes be null but it's assumed that null means key not
found -- the silent failure would be that you thought some key was being
inserted but later on it seemed like it hadn't, with no exception thrown).

Of course it's no magic bullet, but it would help to catch some
null-related errors closer to where the real bug was.

> 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.

There'd need to be a way to declare a type parameter nullable, say

public V? get (K key) {
...
}

means that if it's a HashMap<String,Integer*> the get return type is
Integer rather than Integer* and can still be null. Reference and a few
other classes would need this too, but it would be rare.

We end up needing only two punctuation "warts" in declarations, and one
will only appear, infrequently, in generic classes. (So if two is one
too many, THAT one can be safely changed to something more verbose. "V
|| null" would be pretty clear to anyone who speaks fluent Java.)

>> 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.

At the point where a nullable is assigned to a non-nullable, a run-time
check will be needed. Same as when casting is used; most type-safety is
verified at compile time but in a few spots it needs to have a runtime
check.

> Compare it with ClassCastExceptions: they can only be thrown at explicit
> casts (implicit casts are only possible where no runtime-check is necessary)

Requiring an explicit cast at a nullable->non-nullable assignment where
the compiler cannot prove by static analysis that the RHS isn't null
might be a good idea.

Object foo, bar;
Object* baz, quux, mumble;
...
if (foo == null) {
...
} else {
baz = foo; // OK; foo cannot be null here
mumble = quux; // OK
quux = bar; // Error
quux = (Object*)bar; // OK, but may throw if bar is null
}

The above is with local variables, and assumes foo, bar, and quux are
definitely assigned somewhere between the declarations and the if. With
non-local variables, the possibility of concurrent change to the
reference in another thread means the cast might be needed even on the
"baz = foo;". Allowing omission of the cast there would mean that NPEs
could pop up downstream where baz got used, but any such would indicate
a concurrency issue, so programmers could treat nulls coming OUT of
"non-null" references as prima facie evidence of a race condition in
their code. Race conditions are not something that can generally be made
easier to debug. In this case, they might be. I'd suggest letting "baz =
foo;" with no explicit cast stand, in the case foo is not local, but put
the runtime check in as if a cast were used. Then if a race condition
does cause foo to become null in between the test for null and the
assignment to baz, the NPE is thrown right then and there, inside one of
the blocks of code involved in the race. The programmer knows such an
NPE indicates the need to synchronize that area (and whatever area
nulled foo, if they can find it! But finding one of the areas easily
halves the size of the job).

(Of course, the bytecode has to be equivalent to that from present-Java

baz = foo;
if (baz == null) throw...

and also with the explicit cast

quux = bar;
if (bar == null) throw...

or it's possible for a race condition to get a null into the "non-null"
reference after the test. So, the possible-null has to go in first, then
an exception be thrown if the "non-null" reference isn't actually
non-null. Then if the exception is not thrown the reference always is
not null.)

> 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)

Yes, that is an alternative for arrays.

>> 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.

MD arrays are best off wrapped in some data structure, which would
encapsulate the messy syntax out of general view. It would also tend to
localize bugs if only the elements were declared nonnull in some cases,
and method parameters and returns, but the guts allowed array references
to be null. NPEs from such nulls might occur separated in time from the
cause, but the error would definitely be in that class's implementation.

Even SD arrays are not usually preferable to ArrayList or similar.

> 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.

The need for dummy names at all is rather perverse, in catch clauses and
in private nested classes of all stripes.

Also, some IDEs and compiler options produce warnings on unused
variables. My proposal would allow such warnings to be enabled and still
have warning-free code in these cases, without doing additional dummy
actions.

>> 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).

Oh, goody.

>> StringBuilder sb = new(10);
> I don't like that at all.

Why?

> 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?

Nothing much. It's just that that's not generally what those classes are
*for*.

> 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".

Ugh.

Utility classes need a special declaration, then. Something like
"private null class Foobar" that means it can't be instantiated and it's
an error to have "Foobar x;", Foobar return values, Foobar parameters,
etc.; and of course Foobar cannot inherit from anything not declared
"null" in this way, or have non-static fields or methods. (This in turn
outlaws Foobar implementing a non-empty interface or throwing or
catching a Foobar.)

> What did you mean should actually happen to checked exceptions
> thrown within run() (and not caught there)?

Same as now. Thread dies and a stack dump goes to System.err.

Perhaps there would need to be a way to specify, in a method receiving a
closure parameter, whether it does or does not throw whatever the
closure throws. Closures might have a throws part of their type, and if
the closure is actually invoked in a method that method has to throw or
handle the checked exceptions the closure declares. This requires
full-blown closures, and though a closure literal could just be a
brace-delimited block of code, a closure reference declaration would be
fairly hairy, needing to specify parameter types, return type, and
throws, just like a method, in the general case.

But there's not really any way to avoid that if closures are
implemented, since all of that stuff IS part of the type.

>> 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[].

When the literal is used as the RHS of an assignment (including as a
method parameter or return), the elements would have to be castable to
the type of the LHS of the assignment.

Actually, I think that's about the only time literals are used, so that
seems to eliminate the need for "least common denominator" or similar
type inference of array literals.

In this case, it's passed to a method that wants a Number[] so the
compiler figures out if all of the elements are convertible to Number
and allows it if so, generating a Number[] in the class constant pool
that is passed to the foo method in that method call.

Integer x = 8;
String y = "17";
...
foo({1, 2, 3, 5, x, 13}); // OK, x is an Integer which is a Number
foo({1, 2, 3, 5, x, 13, y}); // Error, y is a String

Actually, the last time I checked, you could assign an Integer[] to a
Number[], but would get a run-time exception if you tried to put a
Double into it via the Number[] reference. One little bit of array
type-unsafety avoided by using collections where possible.

>>> Another entirely different approach could be an
>>> "exemptfromtry { ... }" block inside the try-block.
>> 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 ...

Uggg-leee!

I wasn't proposing to provide more than just try { } continue { } catch
{ } finally { }.

> Someone else would have to find a better verbiage for it.

As a rule, the shorter the verbiage, the better, so long as it remains
readable, and modulo frequency of use.

> Oh, and the finally block would still need to be executed
> even if it was doSomething() that threw an exception.

No duh. Finally would retain the current semantics -- every transfer of
control out of the associated try block goes through the finally code.

>> 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).

Rare does not equal useless, particularly when it's difficult to add the
functionality if you're not Sun (say, because you'd have to rewrite half
the standard library to truly make use of it).

>> 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.

Providing a built-in ReferenceListener just strikes me as a whole lot
nicer than having to actually spawn a separate thread, calling the
blocking poll method and invoking a user-supplied Listener every time it
returned with an enqueued object.

> 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!).

The polling methods that block are actually named "remove" rather than
"poll", but they exist.

remove

public Reference<? extends T> remove()
throws InterruptedException

Removes the next reference object in this queue, blocking until one
becomes available.

Returns:
A reference object, blocking until one becomes available
Throws:
InterruptedException - If the wait is interrupted


is the one I'd use.

>> 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.

Well, I utterly fail to see the reason (if there is any) behind Sun
forcing people to make their own ReferenceQueue listener implementation
using threads, but there might (might) nonetheless be one. :-)

>>> * 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.

public final class Foo {
RealFoo delegate; // Package-private field. No subclassing.
public void method () {
delegate.method();
}
}

public final class Bar () {
private static final class RealFoo implements Interface {
void method () { ... }
void otherMethod () { ... }
}
...
aMethod (Foo foo) {
foo.delegate.otherMethod();
someThing.doWithInterface(foo.delegate);
}
}

works fine. It's not possible to pass a non-Foo to aMethod, because of
compile-time type checking. The delegate RealFoo can implement an
interface but users of Foo don't see it, because they don't see the
delegate field or have any real access to it. However aMethod can use
the interface by extracting the delegate. Finally, since Foo is final
the delegate cannot be exposed by somebody's subclassing of Foo. Only
playing tricks with reflection and serialization might grant access, so,
serious hoop-jumping.

Compiler checks:
* That aMethod is called with a genuine Foo.
* That nobody can mess with the RealFoo delegate outside of the package
with Foo and Bar.
* That RealFoo implements Interface.
* That someThing.doWithInterface is getting an implementation of Interface.

Pretty much everything is compiler-verified here.

Harold Yarmouth

unread,
Nov 2, 2008, 4:36:14 PM11/2/08
to
Joshua Cranmer wrote:
> That said, Mr. Yarmouth was ...

I see no reason for you to publicly insult me, and not even in a
response to one of my own posts, but someone else's.

I did, of course, say that IF they were not appearing as FooEnum$1.class
or similarly THEN there had to be some magic going on under the hood.

Apparently they DO appear as FooEnum$1.class and the like, but only when
they have bodies.

"If X then Y" is not false if X is false. In fact, in formal logic
settings, "If X then Y" is considered to be TRUE if X is false, rather
than even indeterminate. :-)

Joshua Cranmer

unread,
Nov 2, 2008, 4:58:34 PM11/2/08
to
Harold Yarmouth wrote:
> Joshua Cranmer wrote:
>> That said, Mr. Yarmouth was ...
>
> I see no reason for you to publicly insult me, and not even in a
> response to one of my own posts, but someone else's.

How is saying your statement was incorrect an insult?

This was your statement:


> Not on disk, no, but there are four classes in the system at runtime;
> some ClassLoader magic sees to that.

That is not in the "If p, then q" statement that you said.

> I did, of course, say that IF they were not appearing as
> FooEnum$1.class or similarly THEN there had to be some magic going on
> under the hood.
>
> Apparently they DO appear as FooEnum$1.class and the like, but only
> when they have bodies.

Technically, this is false, since they were not appearing as
FooEnum$*.class AND there was no magic going on under the hood. No need
to belabor, though.

Lew

unread,
Nov 2, 2008, 6:16:20 PM11/2/08
to
Joshua Cranmer wrote:
> Harold Yarmouth wrote:
>> Lew wrote:
>>> None of the nasty things Harold says or implies about you are true,
>>> Joshua.
>>
>> Eh? I haven't said any "nasty things" about Joshua.
>
> Read the archives of c.l.j.p of around 1.5-2 years ago, especially those
> posts from someone whose first alias is Twisted. Then you'll understand.

No need to go back that far. I was referring to these remarks:


>> No, it is not, and I will thank you to stop gratuitously insulting me. You,
>> sir, have an attitude problem.

...


>> If you have nothing pleasant or constructive to say, might I suggest that
>> you keep your mouth shut in the future?

...
>> Did you even bother to read my entire post before clicking "Take A Crap All
>> Over It And Send" in your news reader?
...
>> Now you've gone from "nonconstructive" to "just plain bloody-minded".
...

All the sorts of comments that cause Paul to go into a bloody rage when said
to him, but of course, perfectly all right when said by him.

And not true. You were not insulting Paul, gratuitously or otherwise. You
have no attitude problem. You didn't click "take a crap...". And you were
never either "nonconstructive" nor "bloody-minded" (whatever *that* was
supposed to mean).

--
Lew

Andreas Leitgeb

unread,
Nov 3, 2008, 3:22:05 AM11/3/08
to
Harold Yarmouth <hyarmou...@hotmail.com> wrote:
> Andreas Leitgeb wrote:
>> explicitly implementing a non-marker interface then has only
>> one purpose: let the compiler make sure I didn't forget a method.
> Two: you're also making a statement that you are implementing an
> interface deliberately, by doing so, and thus making some sort of
> commitment to observe its contract.

At this point I'm fairly sure all misunderstandings are cleared up,
and I come to the conclusion: I, personally, do not like it.

>>>> Not sure, if you got that idea yourself, or
>>>> from reading <slrngfmc5...@gamma.logic.tuwien.ac.at>.
>>>> (in case google distorts it: "slrngfmc50.4jb.avl" is the part
>>>> before the "at"),
> appears to be addressing me specifically.

The question was directed at you, indeed, but it was intended
such, that other readers (even those with google) would also know
what post I referred to. Google does distort parts of postings,
that resemble email-addresses. Generally I'm even glad about this
feature, as it reduces spam from web-spiders hitting on google's
webinterface. Unfortunately, Message-Ids look structurally like
email addresses, and are therefore "protected", too.

I found the meta-discussion quite wearying. I'd wish we could
both just stick to discussing the ideas, and just ignore anything
meta.

Btw., if you ever actually answered that question, I must
have missed it.

>>> 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.
>
> My proposal overloaded the "extends" keyword for this -- it would
> subclass a non-final class normally, as now, and wrap a final class. You
> appear to want to be able to wrap without subclassing non-final classes.
> For that a new syntax would be needed. Perhaps "implements" followed by
> a class rather than an interface would do the job without adding new
> reserved words to Java?

I now understand your proposal. Obviously (now) it is not the same as
mine. Compared with mine, you left out the class-equivalence part.
Without that, I don't see too much point in the whole thing.
How does a MyString with lots of custom useful methods help me
if I can't bend a literal String into it.

My approach of keeping them equivalent failed with generics erasure.
If I instead target instance-upgrade, that might help, but is an
even deeper paradigm-shift.

>> 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.
> I don't think this would be an issue with Object* object = foobar; or
> Object! object = foobar;, somehow.

As it seems we do disagree here.

>> 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.

This remark was based on my misunderstanding. I thought compile-time
coverage, you think runtime checks.
I accept, but undervalue the merits of runtime-checks.
Otoh., doing it at compile time runs into the problems shown.

I'll just withdraw myself from this topic, until some new ideas come
up. Looking forward to the @NonNull annotation, though.

> Of course it's no magic bullet, but it would help to catch some
> null-related errors closer to where the real bug was.

Yes. I strive for little more magic, though :-)

> There'd need to be a way to declare a type parameter nullable, say
> public V? get (K key) {

The problem is compatibility: any already existing generic class
would not know about the necessity to thusly mark some of it's methods
and consequently make wrong promises as a result. The question mark
could be reversed, such that it would be necessary to hold the notnull-
info on return values. That would solve the compatibility problem
at the cost of being even more confusing.
In that case we could use "*" also within generics, and only if
both a type-parameter is "*"ed (public V* get() ...) AND the type
parameter was "*"ed (List<Integer*>), then the return value would be
known as statically not-null.
All fine, except that I dislike the asterisk as marker.

> Requiring an explicit cast at a nullable->non-nullable assignment where
> the compiler cannot prove by static analysis that the RHS isn't null
> might be a good idea.

> quux = (Object*)bar; // OK, but may throw if bar is null

I consider it a necessity. Except for the asterisk, I like your
example very much: either separate out the null with an "if"
(and deal with the null-case separately), or just cast and have
the NPE thrown eventually.

Concurrency is a beast. Unless we had special idioms that resulted
in: getField...,dup,isnull?,ifyes:NPE,else:putField (pseudo-bytecode),
we'd indeed still need the cast.

>> 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)
> Yes, that is an alternative for arrays.

Anyway it would have to create a copy, or nulls could be sneaked
in later through arrray, and appear in noNullsArray.

>> catch (IOException _) {


> The need for dummy names at all is rather perverse, in catch clauses and
> in private nested classes of all stripes.

but rare and non-verbose enough to not matter all that much.

> Also, some IDEs and compiler options produce warnings on unused
> variables. My proposal would allow such warnings to be enabled and still
> have warning-free code in these cases, without doing additional dummy
> actions.

I don't use such IDEs but I'm fairly sure, they do never barf for
unused parameter names.

>>> StringBuilder sb = new(10);
>> I don't like that at all.
> Why?

Mostly personal taste.

>> What did you mean should actually happen to checked exceptions
>> thrown within run() (and not caught there)?
> Same as now. Thread dies and a stack dump goes to System.err.

But that's not the point of checked exceptions.

>> 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[].
> When the literal is used as the RHS of an assignment (including as a
> method parameter or return), the elements would have to be castable to
> the type of the LHS of the assignment.

That doesn't work. The compiler may need to choose among a couple
of overloaded methods, so it must know the types of the parameters
before even starting out to have a look at all available overloads.

> generating a Number[] in the class constant pool

Actually there is no such thing as an array in the constant pool.
compile this class:
class Test { int[] ia={1,2,3,4}; }
and look at its bytecode.

> Actually, the last time I checked, you could assign an Integer[] to a
> Number[],

By casting it to an Object or Object[] inbetween, iirc.

> I wasn't proposing to provide more than just try { } continue { } catch
> { } finally { }.

I see too little value in that. Therefore I tried to extend it
such that it pays :-)

> The polling methods that block are actually named "remove" rather than
> "poll", but they exist.

I surrender. I don't know what made me miss it.

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

> public final class Foo {
> RealFoo delegate; // Package-private field. No subclassing.

Ah ok, dispersing a public final class's instance that keeps
all its sensitive parts in the delegate does indeed solve it.
But it's ugh-lee ;-)

Andrea Francia

unread,
Nov 3, 2008, 6:45:58 AM11/3/08
to
Harold Yarmouth wrote:
> There's probably plenty of these floating around already, but here's
> bits of mine:
...

What I would like to find in the new JDK is a javadoc tool that support
something like reStructuredText.

--
Andrea Francia
http://andreafrancia.blogspot.com/2008/07/colinux-linux-dentro-windows.html

Lew

unread,
Nov 3, 2008, 7:53:58 AM11/3/08
to
Andreas Leitgeb wrote:
> Harold Yarmouth <hyarmou...@hotmail.com> wrote:
>> Also, some IDEs and compiler options produce warnings on unused
>> variables. My proposal would allow such warnings to be enabled and still
>> have warning-free code in these cases, without doing additional dummy
>> actions.
> I don't use such IDEs but I'm fairly sure, they do never barf for
> unused parameter names.

They have an option to mark unused parameters. I usually leave that option
unchecked, personally.

--
Lew

Mike Schilling

unread,
Nov 3, 2008, 10:25:49 AM11/3/08
to

At times unused parameters are unavoidable, e.g. when a base class
method simply throws an UnsupportedOperationException.

C++ has a pretty nice solution here, though. If a method is declared
as, say,

void method(String s, int)

(that is, when a parameter's type is given with no name) it signals
that that parameter is unused.


Hendrik Maryns

unread,
Nov 3, 2008, 10:32:08 AM11/3/08
to
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Harold Yarmouth schreef:
> Hendrik Maryns wrote:
>> -----BEGIN PGP SIGNED MESSAGE-----
>> Hash: SHA1
>>
>> Harold Yarmouth schreef:
>>> Joshua Cranmer wrote:
>>>> Harold Yarmouth wrote:
>>>> A poor way
>>> No, it is not, and I will thank you to stop gratuitously insulting me.
>>> You, sir, have an attitude problem.
>>>
>>> If you have nothing pleasant or constructive to say, might I suggest
>>> that you keep your mouth shut in the future?
>>
>> Please keep in mind that telling people what to do on Usenet generally
>> doesn’t work.
>
> Please keep in mind that being rude to me without justification
> generally doesn't work.

You have a funny interpretation of the word ‘rude’. (Maybe this was,
but my previous comment certainly wasn’t. I would categorize it under
‘advice’.)

>> How so? Isn’t {array, literal} supposed to create one as well? The
>> method expects an array, after all. Oh, I see, it doesn’t. But even if
>> it expects an Object, there has to be an Object, so the array needs to
>> be created.
>
> In the case that it can be immutable, there could be just the single
> instance. As things stand, the only way to achieve that is to slap it in
> a static final constant. In many cases this is the best practise anyway,
> if the array makes sense to name and make easily changed by programmers.
> But in some cases, it really doesn't. For instance if you have an array
> of the hex digits used in only one place in your code, it's never going
> to change and it's pretty obvious what it is (rather than being a "magic
> value") if it occurs as a literal at point-of-use. It's just that
> currently it can't really, without using the new syntax that will make a
> copy every time.

I’m not following you here, sorry. You snipped some context, but my
question was why you called new Object[] {array, literal} a wasteful
duplicate. Duplicate of what? If your suggested syntax {array,
literal} were allowed, this would create an array instance as well.

You write ‘copy every time’. I think I’m getting it: you suggest
{array, literal} would be interned, similar to "string literal". In
that case the above makes sense and I will not comment on the usefulness
of interning arrays, since I have no idea about it, but right now, they
aren’t, so your argument about a duplicate just doesn’t make sense.

>>> If you're worried that letting immutable arrays get used in such
>>> contexts could somehow cause problems, keep in mind that this is already
>>> possible:
>>>
>>> int[] foo = {1, 2, 3};
>>> ...
>>> fooMethod(1, foo, 3);
>>
>> I don’t get it, foo is mutable.
>
> It shouldn't be, since it's a direct reference to a literal (rather than
> to "new int[]{1, 2, 3}".

Right, so indeed you want literals to be interned. You didn’t write
that in your original proposal, hence the confusion. In the current
setting, your suggested syntax would just be syntactic sugar; if,
however, arrays would be interned (which I seriously doubt will happen,
btw), then it would make more sense.

>>>> So much cleaner IMO.
>>> You're joking, right? It makes an unnecessary temporary collection.
>>
>> True, but ISTR that in Java, creating and abandoning a lot of small
>> classes if more efficient than clinging to one big class.
>
> That's not the issue. The issue is that copying a collection is O(n) and
> copying it twice thus can be significantly slower than copying it once
> if n gets large enough.

ACK.

>>>> There's also this for the last one:
>>>> new HashMap() {{
>>>> this.put("key1", "value1");
>>>> this.put("key2", "value2");
>>>> }};
>>> Now you're making a whole extra class. How efficient.
>>
>> How would this be less efficient? You’re creating a HashMap anyway.
>> Oh, you mean the extra class object. I doubt it will make a difference.
>
> It works, but it's crude and has crummy and verbose syntax.

Oh, I totally agree with you on that one. I would simply write
Map<Kye, Valeu> vars = new HashMap<Kye, Valeu>();
vars.put(kye1, valeu1);
vars.put(kye2, valeu2);

And most of the typing would be done by Eclipse.

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

iEYEARECAAYFAkkPGXgACgkQBGFP0CTku6Mg3ACgwmuueNLHEQffdVjxeyB00vGM
Vl0AnRP6bJaHb6PXKiEqfoQ2/u8WjbpC
=/8f6
-----END PGP SIGNATURE-----

Andreas Leitgeb

unread,
Nov 3, 2008, 10:51:33 AM11/3/08
to
Mike Schilling <mscotts...@hotmail.com> wrote:
> C++ has a pretty nice solution here, though. If a method is declared
> as, say,
> void method(String s, int)
> (that is, when a parameter's type is given with no name) it signals
> that that parameter is unused.

That is exactly what Harold proposed for Java.

My own opinion is, that it's not worth the trouble
changing Java in this particular point.

Hendrik Maryns

unread,
Nov 3, 2008, 10:57:37 AM11/3/08
to
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Harold Yarmouth schreef:
> Hendrik Maryns wrote:
>> -----BEGIN PGP SIGNED MESSAGE-----
>> Hash: SHA1
>>
>> Harold Yarmouth schreef:
>>> Mark Space wrote:
>>>> Harold Yarmouth wrote:
>>>>> * Provide a better way to deal with OutOfMemoryError or low memory in
>>>> Hmm, I haven't looked at any existing frameworks for using
>>>> SoftReferences, but I'd head over to Apache.org and take a look.
>>> I'm not presently in the market for a web server, but thanks anyway. :-)
>>
>> I think you don’t understand.
>
> I think I'm beginning to find unprovoked personal insults quite
> tiresome. If Emily Post ever stumbled across this newsgroup, she'd go
> white as a sheet!

Since when is pointing out a misunderstanding an insult?

>>> Plus, nobody goes looking for third party collection classes. They go
>>> looking for third-party math libraries, web app frameworks, other
>>> domain-specific libraries, and ImageIO plugins and the like.
>>
>> Well, they should be.
>
> No; the needed gamut of collection classes should be (and mostly already
> is) in java.util.

I agree with that, but it doesn’t make the statement less true that, if
java.util (or whatever other package provided by Sun) does not contain
the wanted behavior, it is smart to go look for libraries that do
provide it. Other people probably have thought about that problem
before, and probably longer than you have (yet).

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

iEYEARECAAYFAkkPH3EACgkQBGFP0CTku6O+5ACeKxOaNXtQ9EApxS0VJjKkKIfQ
ob8An3IHXswYWigRc0Edi6x7QKV99u73
=c5fp
-----END PGP SIGNATURE-----

Hendrik Maryns

unread,
Nov 3, 2008, 11:28:11 AM11/3/08
to
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Harold Yarmouth schreef:
> Hendrik Maryns wrote:
>> -----BEGIN PGP SIGNED MESSAGE-----
>> Hash: SHA1
>>
>> Harold Yarmouth schreef:
>>> Andreas Leitgeb wrote:
>>>> Harold Yarmouth <hyarmou...@hotmail.com> wrote:
>>>> Also, for unused method-arguments, the name is usually referred to
>>>> by the javadocs. You do javadoc your methods, don't you?
>>> My anonymous inner class actionPerformed methods?
>>>
>>> You're joking, right?
>>
>> I wouldn’t have been. Ok, Javadoc is unnecessary, but for maintenance
>> purposes some comment makes sence.
>
> It's generally pretty clear what this does in GUI setup code:
>
> FooButton.addActionListener(new ActionListener() {
> public void actionPerformed (ActionEvent e) {
> fooAction();
> }
> }
>
> with
>
> private void fooAction () {
> ...
> }
>
> somewhere else in the class.

You’re right, I should probably start refactoring my code to extract
some more methods out of anonymous inner classes.

>>> On the flip side, the compiler's not permitting "abstract final" is
>>> silly, since it would be useful for making one of those static-utilities
>>> 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.
>>
>> You are stretching the intended semantics of ‘abstract’ here. It is
>> meant to mean: this class should be subclassed to fill in functionality.
>
> It is meant to mean "this class cannot be instantiated".

Since we don’t agree here, it seems like arguments are needed. I’d
start with http://en.wikipedia.org/wiki/Abstract_type and claim that it
favors my view of the matter: an abstract class is supposed to be
subclassed. A final class forbids this and as such the combination of
those keywords if forbidden.

> I can't think
> of anything in Java much more "abstract" (in the English sense) than a
> utilities class with no instances.

Fine, but the keyword has its specific semantic meaning and as is often
the case in computer languages, these do not always relate to the
meaning of the word in the real world.

>>>>> * Have array constructors added to the collection classes:
>>>> If the previous item has a solution, then this one can easily be done
>>>> by appending .toList() to the array-literal.
>>> Wasteful in the extreme. Not just one intermediate object, but probably
>>> actually N+1, and a whole extra O(N) copy of the collection.
>>
>> Mind elaborating how you get these numbers?
>
> Copy array into list, copy list into some other collection, instead of
> copy array into some other collection.

You do know that the objects themselves are not copied, only references?
But still, you are right, it is a double copy.

>>>> Another entirely different approach could be an
>>>> "exemptfromtry { ... }" block inside the try-block.
>>> Oh, my God. Uggg-leee!
>>
>> But feels more in line with the current syntax to me.
>
> But uggg-leee!

LOL

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

iEYEARECAAYFAkkPJpsACgkQBGFP0CTku6Nv3wCffpMifdDPczyupoyjvRF81cvG
tgIAoKG+bQn8CVJuBi4IH6PHZID84e70
=gX0V
-----END PGP SIGNATURE-----

Hendrik Maryns

unread,
Nov 3, 2008, 11:48:59 AM11/3/08
to
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Andreas Leitgeb schreef:


> Harold Yarmouth <hyarmou...@hotmail.com> wrote:
>> Andreas Leitgeb wrote:
>>> catch (IOException _) {
>> The need for dummy names at all is rather perverse, in catch clauses and
>> in private nested classes of all stripes.
> but rare and non-verbose enough to not matter all that much.
>
>> Also, some IDEs and compiler options produce warnings on unused
>> variables. My proposal would allow such warnings to be enabled and still
>> have warning-free code in these cases, without doing additional dummy
>> actions.
> I don't use such IDEs but I'm fairly sure, they do never barf for
> unused parameter names.

Oh, but you can make them to. E.g. Eclipse: Window → Preferences → Java
→ Compiler → Errors/Warnings → Parameter is never read: you can set it
to Ignore, Warning or Error.

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

iEYEARECAAYFAkkPK3sACgkQBGFP0CTku6MEsACfaHn9uryH0UJZDtEf1c4flk7m
YZsAn3RhvcG7TtpS3i20HPQbC29jwO1g
=TWo+
-----END PGP SIGNATURE-----

Andreas Leitgeb

unread,
Nov 3, 2008, 12:19:05 PM11/3/08
to
Hendrik Maryns <gtw3...@sneakemail.com> wrote:
>> I don't use such IDEs but I'm fairly sure, they do never barf for
>> unused parameter names.

> Oh, but you can make them to. E.g. Eclipse: Window → Preferences → Java
> → Compiler → Errors/Warnings → Parameter is never read: you can set it
> to Ignore, Warning or Error.

Lew (iirc) also said so.
I fail to see any sense in this option, and even more so (fail) as it
even seems to be a Java-specific option. (I'd rather understand it,
if it were an "all-languages, incl C++" scoped option.)

To me it seems about as useful as an option that warns me about
methods that do not have any multiplications in their body.

Why would anyone turn this option on? I'm curious.
I might of course just miss a sane usecase.

Hendrik Maryns

unread,
Nov 3, 2008, 11:50:30 AM11/3/08
to
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Andrea Francia schreef:


> Harold Yarmouth wrote:
>> There's probably plenty of these floating around already, but here's
>> bits of mine:
> ...
>
> What I would like to find in the new JDK is a javadoc tool that support
> something like reStructuredText.

I’d like to see Javadoc generated HTML validate (preferably in Strict,
but even Transitional would be a start), or have an option to generate
XHTML.

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

iEYEARECAAYFAkkPK9YACgkQBGFP0CTku6NaagCfUKWgQ1OWTID12S2oW2hFDWUb
7kkAoKIZmOoQcQ+LavRMyEhcGUve/GWZ
=wVBa
-----END PGP SIGNATURE-----

Mike Schilling

unread,
Nov 3, 2008, 2:20:50 PM11/3/08
to

It's a fully compatible change (all existing code still works) and has no
run-time consequences; to me, that means the bar for making the change is
low. It would be unfortunate to make it the only syntax change in a
release, since it forces changes to all compilers, debuggers, code
analyzers, etc, but if it's only one of several changes, it would probably
be the most minor one.


Harold Yarmouth

unread,
Nov 3, 2008, 2:21:37 PM11/3/08
to
Hendrik Maryns wrote:
> Harold Yarmouth schreef:
>> Hendrik Maryns wrote:
>>> Harold Yarmouth schreef:
>>>> Joshua Cranmer wrote:
>>>>> A poor way

>
> You have a funny interpretation of the word ‘rude’.

I don't think so. If I say something, and someone pops up and bluntly
says "a poor way", then that someone was rude, at least by the standards
of civil discourse in my particular neck of the woods (if not, say,
those in New York City).

There are far more diplomatic ways to express a difference of opinion,
ones that do not impugn publicly the competence or intelligence of
whoever you are disagreeing with.

Why are you jumping into what's essentially become a personal argument
between me and Joshua Cranmer, anyway? It has nothing whatsoever to do
with Java. Really you ought to just let it drop.

On a side note, there seem to be several people here who are prone to be
disdainful and disrespectful to anyone that they don't agree with.
Whether it's their intention or not, they give off a distinct aura of
having the attitude that anyone that they don't agree with on matters of
opinion is an imbecile.

I wonder why this is? (Perhaps they are from New York?)

> I’m not following you here, sorry. You snipped some context, but my
> question was why you called new Object[] {array, literal} a wasteful
> duplicate. Duplicate of what? If your suggested syntax {array,
> literal} were allowed, this would create an array instance as well.

A single (unmodifiable) instance at class-load time instead of an
instance every time the new-expression was evaluated.

> You write ‘copy every time’. I think I’m getting it: you suggest
> {array, literal} would be interned, similar to "string literal".

Yes, when the array elements were compile-time constants. But having to
use "new Foo[]" at point of use would defeat that, since it would create
a copy every time. When a modifiable array is needed, this syntax would
still be available to make a modifiable copy of the constant array; it
just wouldn't be mandatory.

> your argument about a duplicate just doesn’t make sense.

Your failure to understand it is not the same thing as me writing
nonsense, and I'll thank you to stop being insulting towards me in public.

> Right, so indeed you want literals to be interned. You didn’t write
> that in your original proposal, hence the confusion. In the current
> setting, your suggested syntax would just be syntactic sugar

Even that, by itself, is not useless.

If your dislike of this proposal is out of concern that it will be
abused and arrays that *should* be named and placed in the constant
declarations won't be, please keep in mind that your argument against it
is then also an argument in favor of banning integer or string literals
in method calls, among other things.

>>>>> There's also this for the last one:
>>>>> new HashMap() {{
>>>>> this.put("key1", "value1");
>>>>> this.put("key2", "value2");
>>>>> }};

>> It works, but it's crude and has crummy and verbose syntax.
>
> Oh, I totally agree with you on that one. I would simply write
> Map<Kye, Valeu> vars = new HashMap<Kye, Valeu>();
> vars.put(kye1, valeu1);
> vars.put(kye2, valeu2);

That's just going back to square 1.

Joshua Cranmer

unread,
Nov 3, 2008, 2:22:50 PM11/3/08
to
Harold Yarmouth wrote:
> There's probably plenty of these floating around already, but here's
> bits of mine:

FWIW, this is a useful link that I just found today:
<http://developers.sun.com/learning/javaoneonline/j1sessn.jsp?sessn=TS-5581&yr=2008&track=javase>.

It's a presentation of some key features that should make Java 7 and
also some guidelines for new features (including how to formally propose
them!).

In short, what's in:
> * Add some way to specify that something should never be null. Perhaps a
> ! or a * before or after the variable name or type name.

@NotNull, of course (see slide 46). Other aides are @Interned,
@Readonly, and @Immutable (see JSR 308). They actually spend a slew of
slides on how this entire process works.

What's probably out:
> * When a type has a one-argument plus() method, + can be used when the

From the slides (49):
Long-term evolution: areas of non-interest
* User-defined operator overloading
* Multimethods
* Macros
* Dynamic typing [this is especially a "over my dead body", as they
stress at multiple times the value of static typing.]

Sounds like operator overloading is going to face an uphill struggle.

> * Full closures.

The presentation is mum on closures--not surprising since there are
equally vocal activists on both sides decrying that Java is (hyperbole
here) crap for not having them and that Java will be crap if it has them
(As Neil Grafter once pointed out, BGGA is the only closures solution
its main proponents will accept, but it's also the only closures
solution that is a non-starter for its detractors). On the whole,
though, the language they use seems to indicate to me that they would be
extremely wary of accepting closures. Note that it may merely be
confirmation basis, since I personally am wary of closures (slide 9 is
the strongest basis for this statement that I see).

The said presentation dealt with language issues and not API issues.
With respect to language issues, this quote from Gosling is appropriate:
"Just say no, until threatened with bodily harm."

Several of the language features you present would probably, at least in
their current forms, violate several of the conditions they give for new
language features. In any case, they do tell you how you would go about
suggesting features, i.e., the Kitchen Sink Language approach (better
known as "actually implement it and see what happens.").

Harold Yarmouth

unread,
Nov 3, 2008, 2:26:04 PM11/3/08
to
Joshua Cranmer wrote:
> Harold Yarmouth wrote:
>> Lew wrote:
>>> None of the nasty things Harold says or implies about you are true,
>>> Joshua.
>>
>> Eh? I haven't said any "nasty things" about Joshua.
>
> Read the archives of c.l.j.p of around 1.5-2 years ago, especially those
> posts from someone whose first alias is Twisted. Then you'll understand.

I don't. *He* may have said nasty things about Joshua, but I don't see
how that is at all relevant to the question of whether or not *I* have
done so.

And if he did so two whole *years* ago, and no more recently than
three-quarters of that span, then it seems fruitless to dredge up such
ancient history anyway. Fruitless and, perhaps, dangerous -- do you want
to reignite some presumably-acrimonious dispute from ages past? I'd have
thought you had better uses for your time, as with everyone else in this
newsgroup who'd have to read or filter all of the resulting
probably-non-Java-related spewage.

In short, this Twisted might search usenet for mentions of his name, or
might still be lurking, and now he might pounce. And none of this has
anything whatsoever to do with me anyway.

Joshua Cranmer

unread,
Nov 3, 2008, 2:37:02 PM11/3/08
to
Harold Yarmouth wrote:
> Joshua Cranmer wrote:
>> Harold Yarmouth wrote:
>>> Lew wrote:
>>>> None of the nasty things Harold says or implies about you are true,
>>>> Joshua.
>>>
>>> Eh? I haven't said any "nasty things" about Joshua.
>>
>> Read the archives of c.l.j.p of around 1.5-2 years ago, especially
>> those posts from someone whose first alias is Twisted. Then you'll
>> understand.
>
> I don't. *He* may have said nasty things about Joshua, but I don't see
> how that is at all relevant to the question of whether or not *I* have
> done so.

I was referring to the fact that (in my eyes at least), Lew was in part
parodying Twisted.

Harold Yarmouth

unread,
Nov 3, 2008, 2:40:45 PM11/3/08
to
Lew wrote:
> All the sorts of comments that cause Paul to go into a bloody rage when
> said to him, but of course, perfectly all right when said by him.

Once again, I don't see any relevance. What some guy named Paul would or
would not do in response to some remarks has no bearing on things when
those remarks were said to Joshua Cranmer instead, and whether or not he
would say the same remarks has no bearing on whether or not I would.

> And not true. You were not insulting Paul, gratuitously or otherwise.

No, he was insulting me.

Why do I have the funny feeling that I've just stepped into the Twilight
Zone or something? I propose some things for Java, which is constructive
and on-topic; Joshua replies solely to dump on me, for some reason that
only his therapist is probably qualified to assess; I take umbrage at
being dismissed in such a disdainful manner with little in the way of
actual argument and with zero diplomacy whatsoever; and then you, for
some reason, take umbrage at my actually speaking up in my own defense
and in defense of my suggestions. And then people start talking about
some ancient dispute between Joshua and some other guy, and drop the
name of some *other* other guy, and seem to think that it's somehow
relevant.

Is this the general treatment people can expect here if they suggest
that something about Java be changed? To have their fairly long and
detailed suggestions rejected summarily with a brusque "that's awful"
type of reply, one that doesn't even hint that the replyer even bothered
to read or think about the proposal in detail before making his
judgment, and one that implies that his judgment carries some kind of
official stamp of finality -- that his opinions on the matter are as
good as facts?

And is disagreeing with such a person some kind of taboo here? The
over-the-top reaction to my standing up to what looked more like
bullying than reasoned criticism certainly seems to suggest so.

If that is indeed the case, then I won't be posting to this group any
more, once I have disentangled myself from this debate and the one in
the Date/Calendar thread.

(Note that I have not claimed that Joshua's response was actually not
based in reason; for all I know, it actually was. But it was phrased in
a manner that didn't indicate that it was -- just a quick brush-off,
without any written reasoned explanations for his opinions and
disagreement with my proposals. If he had real, thought-out reasons for
rejecting something, though, why not explain his reasoning? Why just
appear to be dismissing it out of hand, *and* in a manner that suggests
that he thinks I'm an idiot? And even if he *does* think that I'm an
idiot for proposing some of those things, why make that opinion public,
when doing so can accomplish nothing except to possibly start a fight
that in turn can not conceivably serve any legitimate,
Java-discussion-related purpose here? Where I come from, people are
taught from an early age that if you disagrees with someone else's ideas
you should explain, rationally and without name-calling or other
nastiness, why you disagree, or simply ignore them, rather than try to
start a fight.)

It is loading more messages.
0 new messages