7.0 wishlist?

H

Harold Yarmouth

Hendrik said:
Harold Yarmouth schreef:

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.

The only thing relevant here is the Java specification, and what it says
about abstract in a class declaration is that it makes the class
uninstantiable, also allowing it to have abstract methods.
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.

The meaning of the word in the JLS, on a class declaration, is
"uninstantiable and permitted to have abstract methods". And nothing
*else* in the language presently means "uninstantiable". (Having a
private constructor and no non-private ones has the effect, but does not
declare it as a first-class intention.)

Perhaps there should be something else in the language that can be used
to specify "uninstantiable, but not an abstract type in the Wikipedia
sense", but presently there is none, so I suggested being able to fully
use what's already there.

If you'd prefer to add a new reserved word and maybe break lots of old
code, though, you go right on ahead and suggest it. :)
You do know that the objects themselves are not copied, only references?

Of course. Still, 2*O(n) means the increase is itself O(n).
 
H

Harold Yarmouth

Joshua said:
How is saying your statement was incorrect an insult?

Isn't it bloody obvious? You've basically called me either a liar or
stupid in front of an audience. And you expect that not to get my back up?
This was your statement:

That is not in the "If p, then q" statement that you said.

Yes, it was, when placed in context. The previous poster had said that
he didn't see any Foo$N class files on disk. My reply was meant to
indicate that if it wasn't generating class files on disk, then it was
generating them on the fly in some manner.

Now we know exactly when it does which.
Technically, this is false

Technically, you are an asshole.

This newsgroup exists for the purpose of discussing Java programming,
not debating whether some particular person is a moron (or perhaps a
liar). Your use of the newsgroup as a vehicle for personal attacks and
attempts to undermine public perceptions of my competence, intelligence,
or integrity, therefore, is an ABuse of the newsgroup and should cease
forthwith.

Oh, and by the way, enum constants definitely DO appear as
FooEnum$1.class and the like when (and apparently only when) they have
bodies. The physical evidence says so. If you have some disagreement,
then, I suggest you take it up with Andreas Leitgeb's hard disk. It's
the filesystem on that drive that is really disagreeing with you, it
seems. :)
 
H

Harold Yarmouth

Andreas said:
The question was directed at you, indeed

I found the meta-discussion quite wearying. I'd wish we could
both just stick to discussing the ideas, and just ignore anything
meta.

Unfortunately, some people seem not only to be unwilling to do so, but
all too willing to make public insinuations about other peoples'
competence, honesty, or intelligence, which those people then naturally
feel the need to publicly dispute in turn.

It would help if everyone tried to keep a level head and, however
annoyed or frustrated they might become when someone persists in
disagreeing with them about something, made an effort to bite back any
insults they felt the urge to sling.

That includes subtle put-downs, insinuations, and general rudeness,
condescension, and treating of someone as an idiot or a child, as well
as explicit namecalling and accusation-leveling.
I now understand your proposal. Obviously (now) it is not the same as
mine.

Though it has overlaps.
Compared with mine, you left out the class-equivalence part.
Without that, I don't see too much point in the whole thing.

I fully intended the wrap to test true with "instance of" the base, be
castable to the base, and so forth. You want two-way equivalence, which
is fine for a separate "wraps" type syntax (but obviously not for
"extends").
My approach of keeping them equivalent failed with generics erasure.

Yeah, you might have to cast it back to the wrapper type sometimes.
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.

Compile-time checks can be a part of it -- determining where the
run-time checks are unnecessary, and perhaps requiring an explicit cast
in certain cases.
I'll just withdraw myself from this topic, until some new ideas come
up. Looking forward to the @NonNull annotation, though.

Annotation, schmannotation. I want it to be an integrated part of the
type system, not a bag on the side. Annotations are verbose and might
not be usable on generic type parameters.
Yes. I strive for little more magic, though :)

You'll just have to settle for what's technically feasible, like all of
us. :)
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.

Well, java.util and other cases in the core APIs would be updated along
with Java as a whole. Sources compiled as Java 6 or earlier would be
assumed able to return null (so a get() in a generic MyMap in a
third-party library somewhere would be assumed able to return null, even
for a MyMap<Key, Value*>, until MyMap was compiled with Java 7).

Another option is to assume type parameter returns can be null unless
marked with a ?, and then they may only be null if the type parameter is
not non-nullable:

V get () -> may be null
V? get () -> may be null if <Key, Value>, but not if <Key, Value*>
V* get () -> may not be null
Object get () -> may be null
Object* get () -> may not be null
The question mark could be reversed, such that it would be necessary
to hold the notnull-info on return values.

Indeed. See above.
That would solve the compatibility problem at the cost of being even
more confusing.

I don't think it's that confusing. No more than generics already is,
anyway. :)
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.

Got another (equally brief) preference? The specific choice of asterisk
(and question-mark) is negotiable. :)
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.

As long as the NPE is thrown by the cast, not somewhere downstream later
on; the latter is going back to square 1 with null-safety.

Probably the asterisk is bothersome to C programmers who read the above
as a cast of bar to pointer-to-Object. As I said, the specific symbol is
negotiable, but it should be brief, preferably one
not-allowed-in-identifiers punctuation character.
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.

Nah, just put in the runtime check if it cannot be null without a
concurrency bug, but might be with one. Concurrency bugs show up as odd
effects in odd places (when they don't show up as deadlocks) anyway. At
least an NPE in seemingly-null-safe could would then be prima facie
evidence of thread-unsafety in the null's source chain, and with a
runtime check on the reference assignment the NPE will occur in one of
blocks that participated in a race condition instead of somewhere random
later on.

Putting runtime checks for null at sites other than where they already
occur and explicit casts could also be something done when compiling for
debug and not when compiling for production, or something enabled at
runtime. I'd suggest:

reference* = local; // No check without explicit cast. No cast needed
// if static analysis says local isn't null.
reference* = (Foo*)foo; // Run-time check.
reference* = foo*; // No check, no cast needed
reference* = foreign; // No cast needed if static analysis says foreign
// isn't null without concurrent modification.
// Run-time check though.

These producing, respectively, bytecode equivalent to the following Java
6 code snippets:

reference = local; // reference* = local;

reference = foo; // reference* = (Foo*)foo;
if (reference == null) throw new NullPointerException();

reference = foo; // reference* = foo*;

reference = foreign; // reference* = foreign;
assert reference != null;


Disabling assertions would mean an NPE at a downstream use of reference
if foreign got nulled concurrently; enabled, an AssertionError at the
point of assignment, right smack in the middle of one of the pieces of
concurrent code that is involved in a race-condition bug.

This seems to me to strike the best balance between performance and
safety/bug-detection; null is checked for where it really needs to be
checked for anyway, and nulls that would be secondary to concurrency
bugs at worst are no harder to track down than presently, and may become
easier to do so when assertions are enabled for debugging.
Anyway it would have to create a copy, or nulls could be sneaked
in later through arrray, and appear in noNullsArray.

Ugh. Another reason to prefer using collections. And a reason not to
allow Foo said:
but rare and non-verbose enough to not matter all that much.

Rare? You obviously don't write a lot of action listeners or exception
handlers, unless the former are shared among many components and the
latter are always doing an e.printStackTrace(). :)
I don't use such IDEs but I'm fairly sure, they do never barf for
unused parameter names.

Barf, no, warn, yes, depending on settings.
But that's not the point of checked exceptions.

That's what PRESENTLY happens if run() throws an exception.
That doesn't work. The compiler may need to choose among a couple
of overloaded methods.

When it's ambiguous, it should use whichever is the best fit based on
low-common-denominator. I don't find method overloads with arrays whose
signatures differ only by array type to be very common anyway.

So if you passed {2, 3, 5, 7, 11, 13} to

void method (Number[] nums)
void method (Integer[] ints)
void method (String[] strings)

it would pick the middle one. Much like overload resolution if you pass
the literal 2 to

void method (Number num)
void method (Integer i)
void method (String string)

right now.
Actually there is no such thing as an array in the constant pool.

That might be worth changing.

As near as I can tell, we don't actually have "true" array literals
right now, just a funny syntax for initializing array-type variables.
Adding "true" array literals would involve adding "true" array constants.
I see too little value in that. Therefore I tried to extend it
such that it pays :)

Even if the results are awful, and require adding reserved words to the
language into the bargain? :)
I surrender. I don't know what made me miss it.

I can now add that I've actually added ReferenceQueueListener and
addReferenceQueueListener to my local utility classes. The tricky bit is
ensuring that the queue itself will be garbage-collectible if no longer
in outside use. For that, I have the thread hold the queue in a
WeakReference<ReferenceQueue> (my, how the tables have turned,
ReferenceQueue!) and if the remove(long timeout) method hits the
timeout, it sleeps for a while holding no other references to the queue.
If it's no longer in use (which presumably means no reference objects
still out there that reference it, and no code that might produce more),
it can go. When the thread comes out of sleep, it gets the queue back
out of the WeakReference, and if it's null, it exits. So the thread
dies. And the static map linking queues to threads (so
removeReferenceQueueListener works, and so there can be one thread per
reference queue with listeners instead of per listener) is a WeakHashMap
so the entry there disappears. The whole affair seems to let everything
involved be collected when not in use.

I also wrote a Cache class using a HashMap and using this to register a
listener to remove mappings that are no longer in use. (It subclasses
WeakReference to add a "key" field, so when the reference listener gets
a reference it can remove the mapping.) I then used it in some existing
code. It appears to work. When I put System.out.println("x") in a
listener I got xs in the console when I dropped references to cached
objects -- surprisingly promptly, even -- and caching and releasing a
fair number of objects, some of them large, doesn't seem to bloat the
process size, suggesting that it's not leaking.

Longer-term use will be needed to see if it definitely performs ideally,
but that I knocked this up in less than three hours and had an immediate
use for it makes me wonder why this functionality is missing from
java.lang.ref.
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 ;-)

The technical term is "encapsulation". ;-)
 
H

Harold Yarmouth

Andreas said:
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.

This suggests two alternatives:

Wrap2 extends Base implements Bar only allowed if all of Bar's method
signatures occur in Base

or a Wrap2 secretly knows it's a Wrap2 once it's been cast to Wrap2
sometime during its life, as it would have to be to be passed to
something expecting a Bar.

You may be right though that this would be too hairy for its limited value.

Although letting Wrap2 implement Bar if Base defacto implemented Bar but
wasn't declared as such would get the "let objects that fit the method
signature of a non-empty interface be used as implementing that
interface, at least with an explicit cast" suggestion implemented as a
side-effect.
That's easily said..., but (I think) impossible to make work.

It's only *impossible* if it's equivalent to the halting problem. :)
 
J

Joshua Cranmer

Harold said:
No, unchecked conversions have other, commonplace uses.
Frameworks/reflection, for starters, and there are other cases where
they can't always be avoided because the compiler sometimes just isn't
smart enough to prove everything the programmer can about what types can
actually be occurring where.

Which is to facilitate migration of generics. Granted, the complete
migration is impossible at this time, but such unchecked conversions
will be unnecessary with reified generics.
My guess is that you're dead-set against operator overloading, probably
at least partly for emotional reasons, and that is why you refuse to
actually seriously read and consider proposals for them, and furthermore
why you respond with mild but noticeable rudeness whenever the subject
comes up here.

Hey! You guessed wrong! I actually support operator overloading. I've
just given a lot of thought to the issue so I've found significant
hurdles to implementation. Your proposals are not adequately addressing
these hurdles.
Sorry, but if you want to explain your reasoning, you'll have to
actually explain your reasoning, not fob me off with some URL that's so
long it won't work (with this news software at least) anyway.

I'm trying to save bandwidth and breath.

[ Snip several paragraphs of information all resulting from an incorrect
assumptions. ]
The contract for .plus should include commutativity. That leaves .times.
There, one could specify that if times is noncommutative there be a
.leftHandedTimes (or whatever name seems most suitable) that reverses
the roles of LHS and RHS.

Operator overloading is (or at least should be) principally used for
mathematical constructs. There are several structures for which
operations are not commutative. Note that, in programming, even regular
addition is not necessarily commutative.

a + b == b + a, right? No.

((byteArray[i++] & 0xff) << 8) + (byteArray[i++] & 0xff) is no
(byteArray[i++] & 0xff) + ((byteArray[i++] & 0xff).
It is not the job of the language designer to enforce against every
conceivable misuse of a language feature, least of all to do so by
simply refusing to add any features at all for fear that they might
otherwise be abused.

You're making assumptions which don't pan out. Study some abstract
algebra and learn that some operations are not invertible.
is not relevant to the present discussion. As I have already indicated,
I am not here to argue with canned replies. I am here to have civil and
intelligent discussions with educated adult human beings.

It's repeating the same thing over and over again. As I said, I do not
wish to repeat myself when it adds nothing new. That would make me a
politician.
But this was not mandatory. It could have been done differently; it just
didn't turn out to be.

Technically speaking, the United States /could/ declare war on China
tomorrow. Probably won't, though. Practically speaking, it is difficult
for Java to not have chosen C++ syntax for various reasons.
So, some things should happen before other things. This is the substance
of your argument that none of them should happen at all?

As I see it, all three would have to happen for any one to be
sufficiently valuable to warrant consideration for inclusion. You then
have three distinct features which will probably not live on their own
but are not sufficiently related to be wrapped up as one feature.
Your experience with "languages such as C and C++" is not relevant. We
are discussing Java. Your experience with Java is thus the only thing
along those lines that would be relevant.

You are discussing inclusion of a C/C++ feature. My experience with the
feature in C/C++ has a very high chance of mapping to what it would be
in Java.
So your objection is now that I was *unoriginal* in some way?

No, my objection is that you've added nothing to the debate. There is
sufficient material to build from, it wouldn't be hard.
If that's your opinion, then you should just ignore the subject whenever
it comes up. Attacking everyone who wants to participate in such
discussions, simply for doing so, is inappropriate behavior and even,
I'd argue, an affront to the concept of free speech.

I'm trying to help you by letting you do something: add value to a
currently valueless debate. Maybe if I can clue you in enough, I can
finally give you the help you need...
I would expect that someone should respect the right of the people to
peacably assemble and discuss Java programming here. If some people here
wish to have a civil, level-headed discussion of operator overloading, I
see nothing in the newsgroup charter to forbid it, or to justify your
hostility towards them for doing so.

Pedantically, we're not discussing Java programming. We're discussing
Java features.

[ More aggravating paragraphs based on a faulty assumption ]

As I said, I don't hate operator overloading. I'd love for it to be
included. It's just that your proposal has flaws for which you have not
found, nor (apparently) seek to find, fixes.
 
J

Joshua Cranmer

Harold said:
Isn't it bloody obvious? You've basically called me either a liar or
stupid in front of an audience. And you expect that not to get my back up?

No. I haven't. You seem to equate being factually incorrect with lying
or being stupid. Lying, first of all, implies that you deliberately told
an incorrect statement, knowing that it was incorrect (which is not the
case, as I see it). Secondly, being stupid and factually incorrect
statements are two orthogonal issues.

Do you think Albert Einstein is stupid? Do you think he never made a
mistake? In fact, he made a mistake: the cosmological constant. But no
one thinks that he is stupid for that.
Yes, it was, when placed in context. The previous poster had said that
he didn't see any Foo$N class files on disk. My reply was meant to
indicate that if it wasn't generating class files on disk, then it was
generating them on the fly in some manner.

Now we know exactly when it does which.

It never generates them on the fly. You can decompile the code to prove
this.
 
L

Lew

Joshua said:
I was referring to the fact that (in my eyes at least), Lew was in part
parodying Twisted.

I was completely parodying Harold and anyone "else" who uses that phrase.
 
L

Lew

Hendrik said:
Since when is pointing out a misunderstanding an insult?

Since the person who misunderstood has a pathological aversion to being
thought "wrong" as if it were somehow reprehensible..
 
L

Lew

Harold Yarmouth schreef:
Hendrik said:
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.

The authority in this matter would be the JLS, ss. 8.1.1.1:
An abstract class is a class that is incomplete,
or to be considered incomplete.

In the example of abstract class 'Point', the JLS goes on to say,
the class Point cannot be instantiated because it is abstract.

It never says it the other way around, that a class is abstract because it is
not intended to be instantiated. /Au contraire/, it explicitly states,
A class type should be declared abstract only if
the intent is that subclasses can be created
to complete the implementation.

Thus, Hendrik is completely correct, and "Harold" is partially correct.
 
A

Andreas Leitgeb

Mike Schilling said:
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.

If the amount of trouble can be reduced, then it might be
worth the reduced amount of trouble :)
 
M

Mike Schilling

Andreas said:
If the amount of trouble can be reduced, then it might be
worth the reduced amount of trouble :)

It doesn't have to be reduced, just mixed in with enough other trouble
that it appears insignificant :)

And that's not entirely silly. It happens sometimes that when I'm
fixing bugs I'll pick a few related "annoying but not urgent" ones and
fix them all at once, so that the cost of reminding myself exactly how
that part of the code works and running the unit tests gets amortized
over all of them.
 
A

Andreas Leitgeb

Harold Yarmouth said:
Andreas Leitgeb wrote: [transparent class wrapping]
Compared with mine, you left out the class-equivalence part.
I fully intended the wrap to test true with "instance of" the base, be
castable to the base, and so forth. You want two-way equivalence,

You wanted castability from wrapper to base, I wanted equivalence.
Equivalence is always symmetric.

[nonnull-ness]
Got another (equally brief) preference?

I found some page that proposed "#" for it, and gave arguments against
doing it with annotatons. It also had some flaws in it, but parts of
it are quite reasonable. I'm talking of:
http://docs.google.com/View?docid=dfn5297z_2kjj2fk
The flaw is with overriding methods that change the null-allowedness.
e.g.:
class Base { void foo(Foo f) { ... } } // Base.foo allows null arg.
class Sub extends Base { void foo(#Foo f) { ... } } // Sub.foo doesn't.
Since the compiler doesn't know what instance is really stored in a
Base typed reference, it cannot do the right check for null, so it's
inevitable to still check for null inside Sub.foo(...)'s body.
Nah, just put in the runtime check if it cannot be null without a
concurrency bug, but might be with one.

That's just the situation at hand:
A (null-allowed) field that at some point happens to be not null
shall be copied into a non-null other field.

At no point in time do we want to risk the null to enter the target
field, because even if we get a NPE afterwards, unrelated code in
a second thread may see the null before the the null-check in this
thread sees it, and thus the goal of "knowing where it happened" would
not be met.

The only ways to get this really safe is to either copy it to a
local variable first, check that, and only on success copy it to
the target, or have the principially same thing happening
on the stack at jvm-level, as I mentioned it above.

[unused parameter names]
Rare? You obviously don't write a lot of action listeners or exception
handlers, unless the former are shared among many components and the
latter are always doing an e.printStackTrace(). :)
Where I get into such situations, I either spend a one-letter name,
or some acronym, like "npe" when catching a NullPointerException,
no matter if I use it or not. I find eclipse's warning about
unused parameters goofy, and would turn it off anyway, if I ever
used eclipse.

Enough for today.
While deleting the rest of the quotes, I saw that I didn't have much to
say about them anyway.
 
H

Hendrik Maryns

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

Harold Yarmouth schreef:
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.

ACK. It is difficult to stay polite if you don’t see the person on the
other side.
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.

You might notice my name up there.
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.

Sorry, see above. OTOH, I think you could be a little less sensible in
this respect. I, for one, would not feel insulted if someone said an
argument of mine doesn’t make sense, provided he provides some arguments.
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.

I didn’t say I dislike this proposal, I explicitly said I do not know
enough of the consequences of this to comment on it and haven’t felt a
strong need for it, yet. But that was after the misunderstanding was
cleared up.
That's just going back to square 1.

Yup, I’m satisfied with square 1 in this respect.

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

iEYEARECAAYFAkkQVsYACgkQBGFP0CTku6OYmwCgjL/yhs3KbZ9KwVvnuS/Vu+CX
kA4AoItMlelfZCixD4TokZE1AMYI6nhO
=Fot/
-----END PGP SIGNATURE-----
 
H

Hendrik Maryns

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

Harold Yarmouth schreef:
To you, perhaps.

Did you think of the ~ as in ≅? Then it does make sense, but ~ is often
used for negation, so also confusing. Whatever, really.
Pair literals could be added, surely.

You are implying interning again. I do not see a direct correspondence
between literals and interning. In fact, I see no reason why [a,b]
would not create a new pair in the background each time. It is only a
question how much trouble the jvm implementors want to go through.

'z' and 15 are also literals, but I doubt there is only one version of
them around in memory, just to illustrate the difference between
interning and literals.

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

iEYEARECAAYFAkkQfU8ACgkQBGFP0CTku6OSCQCeJc1+3GFk3/IGLhIxkCLwqKaV
NyUAoIIfHkuyde5Bk/NGYD3wllUUn3tb
=FKG9
-----END PGP SIGNATURE-----
 
H

Hendrik Maryns

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

Harold Yarmouth schreef:
Pointing out a misunderstanding, in and of itself, is not an insult.

Publicly accusing a specific person of stupidity, on the other hand, is
an insult.

This is a forum for discussing Java programming, not for assigning blame
and arguing over who is at fault.

But now that you've raised the issue of blame and now that my
intelligence and competence have been publicly called into question by you:

If there was a misunderstanding, and if it was a particular person's
fault, then it was your fault, not mine.

When did I write ‘blame’? When did I say you are at fault?
How do you find such? For things like adding .xpm image support you
search for ".xpm image support java" or ".xpm image library java"; for
esoteric math stuff "math library java"; etc.; but searching for
collections will lead directly to Sun's java.util API docs and related
content, and will lead to little else.

Finding Jakarta Commons Collections might be difficult, but my point was
simply that it is worth looking for a library. If you don’t find one,
that’s unfortunate, but no harm is done.
I don't know if this was intended as an insult, or just as a silly
suggestion that nobody be allowed to suggest or ask for anything without
first getting a comp sci Ph.D. or something.

It was not intended as an insult. In fact, I have never in my life
intended anything as an insult. What I tried to point out is that it is
wiser to try to use the wisdom of other people, instead of doing
everything yourself.

Did I say not to suggest? Did I say not to ask? If so, I didn’t mean to.

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

iEYEARECAAYFAkkQfusACgkQBGFP0CTku6N7zQCgoQ7OfeBHpWCkglT1ekcO9kJb
c8wAnRjqbA0rlilw+cxjFTMVu02jOu9q
=8Bbe
-----END PGP SIGNATURE-----
 
H

Hendrik Maryns

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

Harold Yarmouth schreef:
The only thing relevant here is the Java specification, and what it says
about abstract in a class declaration is that it makes the class
uninstantiable, also allowing it to have abstract methods.


The meaning of the word in the JLS, on a class declaration, is
"uninstantiable and permitted to have abstract methods". And nothing
*else* in the language presently means "uninstantiable". (Having a
private constructor and no non-private ones has the effect, but does not
declare it as a first-class intention.)

Perhaps there should be something else in the language that can be used
to specify "uninstantiable, but not an abstract type in the Wikipedia
sense", but presently there is none, so I suggested being able to fully
use what's already there.

If you'd prefer to add a new reserved word and maybe break lots of old
code, though, you go right on ahead and suggest it. :)

I wasn’t aware of that, thanks for explaining.

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

iEYEARECAAYFAkkQfzQACgkQBGFP0CTku6OVnACdGg+w3lV/yiIVOVUBAOLoEyWr
4zgAn11tJEz0YAgeOxYtz/3QpSHQRZ0L
=uX7v
-----END PGP SIGNATURE-----
 
H

Hendrik Maryns

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

Andreas Leitgeb schreef:

[about non-nullability]
I found some page that proposed "#" for it, and gave arguments against
doing it with annotatons. It also had some flaws in it, but parts of
it are quite reasonable. I'm talking of:
http://docs.google.com/View?docid=dfn5297z_2kjj2fk
The flaw is with overriding methods that change the null-allowedness.
e.g.:
class Base { void foo(Foo f) { ... } } // Base.foo allows null arg.
class Sub extends Base { void foo(#Foo f) { ... } } // Sub.foo doesn't.
Since the compiler doesn't know what instance is really stored in a
Base typed reference, it cannot do the right check for null, so it's
inevitable to still check for null inside Sub.foo(...)'s body.

Isn’t this breaking Base.foo’s contract? (You know, Liskov.)

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

iEYEARECAAYFAkkQgLEACgkQBGFP0CTku6N56QCggaAEjfb1UHRg8PhpSx9P7Oiv
w5YAniPXWu8ztKxcbyLaNCb+nVcBd5T6
=GULd
-----END PGP SIGNATURE-----
 
A

Andreas Leitgeb

Hendrik Maryns said:
Andreas Leitgeb schreef:
[about non-nullability]
http://docs.google.com/View?docid=dfn5297z_2kjj2fk
The flaw is with overriding methods that change the null-allowedness.
e.g.:
class Base { void foo(Foo f) { ... } } // Base.foo allows null arg.
class Sub extends Base { void foo(#Foo f) { ... } } // Sub.foo doesn't.

It was not really a flaw, since the mentioned classes (ConcurrentHashMap
and HashMap) are just siblings both derived from AbstractMap. So, finally,
if AbstractMap (and Map) declared it's put(...) to accept only non-null
values, then HashMap and TreeMap could both broaden the domain (i.e. allow
also null) and ConcurrentHashMap leave it as is. All that without breaking
any contracts. Otoh., declaring Map as taking no nulls isn't any likely
to happen...
Isn’t this breaking Base.foo’s contract? (You know, Liskov.)

Yes, it would be this way. It would not be the other way (if
Base.foo took only non-null and Sub.foo accepted null as well).
 
R

Roger Lindsjö

Harold said:
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:

I have used it to get a next() and prev() functionality of enums (think
I used something similar in Pascal or Turbo Pascal). So for me having a
clearly defined value has it's "value" ;-)
 

Ask a Question

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

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

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top