javax.swing.ButtonGroup's add method violates implied contract

K

Kent Paul Dolan

Color me picky, but the javax.swing.ButtonGroup's
add( AbstractButton b) method, which internally adds
the AbstractButton to a Vector<AbstractButton> named
"buttons", seems to me to violate the implied invariant
contract of java.util.Collection's add(E o) method, see:

..../jdk1.5.0_05/docs/api/java/util/Collection.html#add(E)

in that it doesn't return a boolean "true", or alternately
throw an exception, such that a normal return means that
the add of the button was indeed successful, the invariant
mentioned above.

The javac compiler, of course, will then not let a class
derived from ButtonGroup override the add method in
a way that does correctly throw such an error when the
add to the Vector, or to some parallel Vector used in
the extended class, fails.

Am I off in outer space somewhere, or is this really a
Sun design error in the ButtonGroup class?

In my case, I'm trying to add a Vector<Boolean>
in the class derived from ButtonGroup [which could
be better called ExactlyOneButtonSetGroup],
named by me AtMostOneButtonSetGroup,
paralleling "buttons", so that I can store and
reference the state of a button _prior_ to the
action that informs me the button just changed
to a "selected" state, to see if that was _already_
its state, in the interest of creating a "one or zero"
quasi-RadioButton class as recommended in the
ButtonGroup JavaDocs, by using an extra,
invisible JRadioButton in the ButtonGroup, to which
selecting an already selected button will move the
selection.

[I'm sure I'm reinventing a rotating object here, and,
since this is the second time I've had to do so, a bit
surprised this isn't an already provided behavior
in some javax.swing class derived from or parallel
to ButtonGroup. It seems to be a very common third
behavior requirement for stateful toggle buttons
besides the ones already provided as checkboxes
and radio buttons. The "use an invisible radio button"
ploy, while it can be made to work, is a desperate
kludge to avoid having a third standard class that
does this behavior "right", it seems to me.]

xanthian.
 
J

John C. Bollinger

Kent said:
Color me picky, but the javax.swing.ButtonGroup's
add( AbstractButton b) method, which internally adds
the AbstractButton to a Vector<AbstractButton> named
"buttons", seems to me to violate the implied invariant
contract of java.util.Collection's add(E o) method, see:

.../jdk1.5.0_05/docs/api/java/util/Collection.html#add(E)

in that it doesn't return a boolean "true", or alternately
throw an exception, such that a normal return means that
the add of the button was indeed successful, the invariant
mentioned above.

ButtonGroup does not implement Collection, therefore the contract for
Collection.add(Object) is in no way relevant to the form and behavior of
ButtonGroup.add(AbstractButton). The fact that internally the method
may add the specified button to a Vector is an implementation detail,
not relevant to the question. If you nevertheless want to pursue the
matter then you should consider the fact that the more specific contract
of Vector.add(Object) specifies that that method always returns true and
never throws an exception. I really don't see how any of that leaves
you cause for complaint.
The javac compiler, of course, will then not let a class
derived from ButtonGroup override the add method in
a way that does correctly throw such an error when the
add to the Vector, or to some parallel Vector used in
the extended class, fails.

I don't see any correctness issue in this situation. Moreover, adding
an object to a Vector via add(Object) has no defined failure mode, not
even any documented unchecked exception (contrast
Collection.add(Object)), so the specific potential failure you describe
can't happen anyway if every class correctly adheres to its contracts.
Am I off in outer space somewhere, or is this really a
Sun design error in the ButtonGroup class?

I don't see a design error. I don't even see much of a feature hole
because GUI construction is normally a development-time issue; if you
don't want a particular button in your group then don't add it -- the
matter is completely within your control.
In my case, I'm trying to add a Vector<Boolean>
in the class derived from ButtonGroup [which could
be better called ExactlyOneButtonSetGroup],
named by me AtMostOneButtonSetGroup,
paralleling "buttons", so that I can store and
reference the state of a button _prior_ to the
action that informs me the button just changed
to a "selected" state, to see if that was _already_
its state, in the interest of creating a "one or zero"
quasi-RadioButton class as recommended in the
ButtonGroup JavaDocs, by using an extra,
invisible JRadioButton in the ButtonGroup, to which
selecting an already selected button will move the
selection.

That would be a very unintuitive GUI element. Button groups just don't
usually work that way. The ButtonGroup Javadocs suggest instead using a
seperate, normal button that has the effect of clearing the button group
(by programmatically selecting the invisible button), which to me seems
much more usable. Even that is a bit of a hack as far as I am
concerned; button groups aren't *supposed* to be cleared.
[I'm sure I'm reinventing a rotating object here, and,
since this is the second time I've had to do so, a bit
surprised this isn't an already provided behavior
in some javax.swing class derived from or parallel
to ButtonGroup.

As I wrote above, the behavior you describe runs against typical GUI
conventions. I'm therefore unsurprised that the functionality has not
been codifed into the platform library.
It seems to be a very common third
behavior requirement for stateful toggle buttons
besides the ones already provided as checkboxes
and radio buttons. The "use an invisible radio button"
ploy, while it can be made to work, is a desperate
kludge to avoid having a third standard class that
does this behavior "right", it seems to me.]

I don't see this as an issue to do with JCheckBox or JRadioButton at
all, but rather with ButtonGroup. The former are used /with/ the
latter, but it is the latter (ButtonGroup) that drives the behavior
you're talking about. Am I missing something here?
 
K

Kent Paul Dolan

John said:
ButtonGroup does not implement Collection,
therefore the contract for Collection.add(Object)
is in no way relevant to the form and behavior of
ButtonGroup.add(AbstractButton).

Umm, do you really feel that hairsplitting on the
is-a/has-a boundary is a fruitful way to decide if a
design is robust? That's language lawyering, not
architecting.
If you nevertheless want to pursue the matter then
you should consider the fact that the more
specific contract of Vector.add(Object) specifies
that that method always returns true and never
throws an exception.

That is _really_ frightening. Java, whose
"pointerless" design is nevertheless perennially
throwing null pointer errors, has designers who
think, and embed that thought in design, that their
code _cannot_ fail, for something as complex as
Vector? Brrrr.
I really don't see how any of that leaves you
cause for complaint.

More than ever, as it eventuates.
I don't see any correctness issue in this
situation. Moreover, adding an object to a Vector
via add(Object) has no defined failure mode, not
even any documented unchecked exception (contrast
Collection.add(Object)), so the specific potential
failure you describe can't happen anyway if every
class correctly adheres to its contracts.

I don't share your naive trust in the Java compiler
and runtime implementation.
I don't see a design error. I don't even see much
of a feature hole because GUI construction is
normally a development-time issue; if you don't
want a particular button in your group then don't
add it -- the matter is completely within your
control.

What on earth does that have to do with whether
adding to a ButtonGroup, which encapsulates an add
to a Vector, which _is_ a Collection, exposes the
exception that is supposed to be thrown to the
client when add() fails?
That would be a very unintuitive GUI element.

What on earth is "unintuitive" about an "at most
one" set of buttons?

In my case, I have a feature of a graphical display
which can have one of two states, or not appear, so
I want exactly "A or B or neither, but not both". I
_don't_ want to expend 50% more screen real estate
than is necessary to achieve that result.
Button groups just don't usually work that way.

Because, according to its own documentation,
ButtonGroup _is_ the implementor of the JRadioButton
"exactly one" behavior; the button itself _cannot_
implement that behavior, doing so would violate
encapsulation. Thus ButtonGroup "usually", indeed,
_always_, behaves as containing a single set of
radio buttons.

The "issue", if issue there is, is that the "at most
one" behavior is at least as common as the "exactly
one" behavior, but there is no "built-in"
ButtonGroup-paralleling mechanism to implement this
behavior.
The ButtonGroup Javadocs suggest instead using a
sep[A]rate, normal button that has the effect of
clearing the button group (by programmatically
selecting the invisible button), which to me seems
much more usable.

You apparently have screen real-state to give away
on a useless button; I don't. You have besides,
missed that the "none" button is recommended merely
as one of several possible ways to implement that
invisible button, but by then you've already spent a
visible and distinguished button, making the
invisible button completely pointless, and thus that
recommendation purely bad advice.

Selecting an already selected button, in the current
implementation, triggers the same signal as
selecting it when it was unselected, which is an
ambiguating design error by Sun. Doing so should
either do nothing at all, or, as I'm seeking, clear
the button without setting another one. To avoid
that ambiguation of the two situations, the client
would have to do as I am trying to do (have done, in
the case, but without the joy of a better
implementation than Sun permits), by recording the
prior state so it can be checked whether the new
"selection" is merely a redundant click.
As I wrote above, the behavior you describe runs
against typical GUI conventions.

In your apparently limited experience, that might be
so. I've been designing GUIs roughly since that was
even possible, and there are no such "conventions"
known to me.
Am I missing something here?

Sigh. Merely reading comprehension. I was still
writing about ButtonGroup, since the _behavior_ is
implemented at that level. Somehow, you lost grasp
of the discussion along the way when other terms
were mentioned. Better luck this time.

xanthian.
 
J

John C. Bollinger

Kent said:
John C. Bollinger wrote:




Umm, do you really feel that hairsplitting on the
is-a/has-a boundary is a fruitful way to decide if a
design is robust? That's language lawyering, not
architecting.

I don't see any hair splitting here. On the contrary, I find it odd
that you assert that ButtonGroup.add(AbstractButton) should be expected
to have behavior governed by that of Collection.add(Object), simply on
the basis of /using/ Vector.add(Object) internally. If there is a
design error here then I would say that it is in ButtonGroup exposing
details of its implementation of add(), not in
ButtonGroup.add(AbstractButton)'s similarity or dissimilarity to
Collection.add(Object). You are the one who raised the issue of the
Collection contract, and thus I think it very relevant to observe that
ButtonGroup is not bound by that contract. Furthermore, Vector, which
*is* bound by that contract, fulfills it just fine without ever
returning false from its add(Object) method or throwing an exception
(though it might occasionally throw an Error).
That is _really_ frightening. Java, whose
"pointerless" design is nevertheless perennially
throwing null pointer errors, has designers who
think, and embed that thought in design, that their
code _cannot_ fail, for something as complex as
Vector? Brrrr.

Certainly one must either discard the idea of Java being pointerless or
allow that "NullPointerException" is misnamed, but I don't see how that
enters the picture. Classes throw that exception when presented with
nulls that they cannot handle, which is always the result of a bug,
usually one in the client class.

That Vector has no failure mode specific to it, however, is not so
strange. Vectors accept any and all elements, including null, so
Vector.add(Object) never fails on account of the argument. One must
presume that the method is not buggy, but even if it were, it is not
reasonable to expect a defined result if such a bug were triggered. The
remaining failure cases involve general VM conditions that are always
potential failures for any code; foremost among these is an
OutOfMemoryError. Such conditions are rarely, if ever, documented on
individual methods because they don't really "belong" specifically to
any method.

One certainly /could/ complain that Vector's design makes it difficult
to usefully extend the class. I would agree with that. I do not find
anything frightening about it, however. I also don't have much
complaint with not being able to extend Vector, as I have never seen a
good reason to want to do so (present discussion included). It is
almost always the case that giving a class a Vector member is more
appropriate than making it extend Vector.
I don't share your naive trust in the Java compiler
and runtime implementation.

I don't understand your concern. You ultimately have no alternative
*but* to trust the compiler, the runtime implementation, and the
platform library. One tests carefully, to be sure, and works around a
bug in any of those in the rare case that one is found, but *every*
behavior of your program is predicated on the compiler, VM, and library
behaving correctly. If you don't trust that then you cannot use the
language.
What on earth does that have to do with whether
adding to a ButtonGroup, which encapsulates an add
to a Vector, which _is_ a Collection, exposes the
exception that is supposed to be thrown to the
client when add() fails?

The internal addition to a Vector is an implementation detail, more
exposed than it ought to be but an implementation detail nonetheless.
Inasmuch as you are focusing on that detail, I think you are using a
faulty basis for your criticism. The implementation of a method or
class is driven by its design, not the other way around. Furthermore,
as I wrote before, even if you *do* look at the implementation, you have
to observe that the specific kind of Collection used (Vector) *doesn't*
have any defined failure mode for object addition. This is fully
consistent with Collection.add(Object), but more specific in that it
requires that every Vector be able to add every object. Given the
specifications of Vector.add(Object), ButtonGroup.add(AbstractButton)'s
use of that method does not provide any basis for an assertion that the
latter should provide some kind of avenue for a failure message to be
returned.
What on earth is "unintuitive" about an "at most
one" set of buttons?

It is not the "at most one" part so much as the details you described
about your implementation. If you use radio buttons in your button
group then the unintuitive part is that clicking on the selected button
turns it off. If you use check boxes then the unintuitive part is that
no more than one can be selected (though this is probably the most
intuitive of these unintuitive options). If you use some new and unique
(and visually distinguished) type of button then that in itself is the
unintuitive part.
In my case, I have a feature of a graphical display
which can have one of two states, or not appear, so
I want exactly "A or B or neither, but not both". I
_don't_ want to expend 50% more screen real estate
than is necessary to achieve that result.

The advantage of using the extra real estate is in providing an
interface that your users don't find surprising. Yes, your users will
likely learn whatever interface you provide, but it is less work for you
and them both if you provide controls and combinations of controls that
operate in a way that they will understand without special documentation
or support.
Button groups just don't usually work that way.


Because, according to its own documentation,
ButtonGroup _is_ the implementor of the JRadioButton
"exactly one" behavior; [...]

I don't mean ButtonGroup the class, I mean button groups as GUI
elements. They (should) provide "exactly one" selection from a group of
two or more. You do sometimes see button groups with no option
initially selected (more often on web forms than anywhere else), but the
meaning of such a group is nowhere near as clear as the meaning of a
similar group with an extra "none of the above" option selected. Coming
back to the ButtonGroup class, it provides Swing GUIs with button group
behavior consistent with button group behavior in other contexts. As
such, I don't find it lacking.
The "issue", if issue there is, is that the "at most
one" behavior is at least as common as the "exactly
one" behavior, but there is no "built-in"
ButtonGroup-paralleling mechanism to implement this
behavior.

As should be clear by now, I disagree that the behavior you are looking
for is as common as the behavior already provided by ButtonGroup. I
also disagree that the behavior you want is desirable, but if you want
to continue this discussion in that direction then I think it would be
best for both of us to go looking for relevant third-party usability
guidelines / studies / whatever (I have already provided a few such below).
The ButtonGroup Javadocs suggest instead using a
sep[A]rate, normal button that has the effect of
clearing the button group (by programmatically
selecting the invisible button), which to me seems
much more usable.


You apparently have screen real-state to give away
on a useless button; I don't. You have besides,
missed that the "none" button is recommended merely
as one of several possible ways to implement that
invisible button,

No, I didn't miss that, hence my use of the word "suggest." The
suggestion is the only specific one given in the ButtonGroup docs (v.
1.4; haven't checked v. 1.5). That in no way makes it a required
implementation, but it does distinguish that approach relative to other
implementations.
but by then you've already spent a
visible and distinguished button, making the
invisible button completely pointless, and thus that
recommendation purely bad advice.

You do have a point there. Indeed, I think the best option is a visible
"none of these" button in the button group. It is both clearest for the
user and easiest for the programmer. Are you developing for tiny
screens, or something? Otherwise you have an altogether different
problem if the required amount of extra screen space is a concern.
Selecting an already selected button, in the current
implementation, triggers the same signal as
selecting it when it was unselected, which is an
ambiguating design error by Sun.

Yes, I saw that when I looked into the question before my first
response. Here I'll agree that there is an error, though I would
identify it differently: the error is in using AbstractButton as a
superclass of both stateless buttons (JButton / JMenuItem) and stateful
ones (JCheckBox / JRadioButton). Or at least in defining some behaviors
there that shouldn't really be common to both types of button. There is
then a secondary error in allowing ButtonGroup to have any
AbstractButton as a member, when really it should be able to hold only
the latter type (already abstracted as JToggleButton).
Doing so should
either do nothing at all, or, as I'm seeking, clear
the button without setting another one. To avoid
that ambiguation of the two situations, the client
would have to do as I am trying to do (have done, in
the case, but without the joy of a better
implementation than Sun permits), by recording the
prior state so it can be checked whether the new
"selection" is merely a redundant click.

Yes, I would agree that a different type of button class (or different
behavior of the existing classes) would afford a better solution than
the type of shenanigans you have described implementing in your
ButtonGroup subclass. On the other hand, I wouldn't myself have
implemented any of it in the first place.
In your apparently limited experience, that might be
so. I've been designing GUIs roughly since that was
even possible, and there are no such "conventions"
known to me.

There are lots of GUI design manuals and guides, and for the most part
they describe very consistent behavior of the common GUI elements. You
cannot be unaware that these exist, particularly given your extensive
GUI design experience. Not all distinguish between "exactly one" button
group behavior and "at most one" behavior, however. Here are some:

http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHIGuidelines/index.html
http://developer.kde.org/documentation/standards/kde/style/basics/index.html
http://axp16.iie.org.mx/Monitor/v01n03/ar_ihc2.htm
http://benroe.com/files/gui.html

Notably, for HTML forms, RFC 1866 states "At all times, exactly one of
the radio buttons in a set is checked. If none of the <INPUT> elements
of a set of radio buttons specifies `CHECKED', then the user agent must
check the first radio button of the set initially." (section 8.1.2.4)
User agent compliance on this point varies, however.

The Gnome radio button docs state "Exactly one radio button should be
set in the group at all times. The only exception is when the group is
showing the properties of a multiple selection, when one or more of the
buttons may be in their mixed state."
(http://developer.gnome.org/projects/gup/hig/draft_hig_new/controls-radio-buttons.html)

As to my GUI design experience (of which I do have some), it is not
nearly so important as my GUI *user* experience, because the latter is
where I get my expectations of how GUI elements should operate. I
daresay the same is true of most of your users. I have never
encountered a radio button that toggled off when I clicked it, and
therefore I do not expect such behavior. I have occasionally
encountered controls that looked like check boxes but acted like radio
buttons; this behavior is unexpected and thus less usable, but at least
it's easy enough to adapt to.
Sigh. Merely reading comprehension. I was still
writing about ButtonGroup, since the _behavior_ is
implemented at that level. Somehow, you lost grasp
of the discussion along the way when other terms
were mentioned. Better luck this time.

Do continue with the pot shots if your objective is to persuade me to
drop this conversation. Otherwise please refrain.

Your original post asked for opinions on whether ButtonGroup was
ill-designed for one or both of two reasons:

1) The lack of any success / failure information returned by
ButtonGroup.add(AbstractButton), and

2) ButtonGroup's lack of direct support for an "at most one" selection mode.

I take (1) as a general OO design question, and I responded accordingly.
I take (2) as an issue revolving around general GUI design and
behavior issues, and I responded accordingly, mostly with comments not
specific to Java or Swing. One cannot discuss whether or not
ButtonGroup's behavior is appropriate without some kind of context for
what its behavior ought to be. If you did not like the directions I
took the discussion then I can only apologize, but I assure you I did
and do have a firm grasp of it. For what it's worth, you have
significant control of the lines on which this discussion continues.
 
M

Monique Y. Mudama

Umm, do you really feel that hairsplitting on the is-a/has-a
boundary is a fruitful way to decide if a design is robust? That's
language lawyering, not architecting.

I absolutely disagree. The user of an API shouldn't have to know
what's going on under the hood. "is-a" is therefore important to the
user of an API; "has-a" should *not* be.
 
K

Kent Paul Dolan

Monique said:
Kent Paul Dolan penned:
I absolutely disagree. The user of an API
shouldn't have to know what's going on under the
hood. "is-a" is therefore important to the user
of an API; "has-a" should *not* be.

Umm, but that's precisely the point. ButtonGroup,
conceptually, and thus by implication contractually,
is-a Collection, and so should obey the contract for
Collection that failure to add an Object to a
Collection warns the client-user of the problem by
throwing an exception.

That ButtonGroup happens to _implement_ its
"Collection"-ness by a has-a mechanism rather than
an is-a mechanism is an implementation detail which
SHOULD NOT CONCERN the functionality's "consumer".

But in fact, ButtonGroup fails to keep the expected
contract for a Collection, violating the Principle
of Least Astonishment. Leaving the user-client
unwarned when the addition of a JToggleButton to a
ButtonGroup fails, is, it seems to me, lousy
software engineering as well.

IMAO

xanthian.
 
M

Monique Y. Mudama

Umm, but that's precisely the point. ButtonGroup, conceptually, and
thus by implication contractually, is-a Collection, and so should
obey the contract for Collection that failure to add an Object to a
Collection warns the client-user of the problem by throwing an
exception.

Um, no. ButtonGroup extends Object, as do all Objects. It also
implements Serializable. It's not a Collection. The fact that you
think it looks like it should be a collection just because it has
several of something is irrelevant.
That ButtonGroup happens to _implement_ its "Collection"-ness by a
has-a mechanism rather than an is-a mechanism is an implementation
detail which SHOULD NOT CONCERN the functionality's "consumer".

I'm sorry, but I can't follow you down that path. If the designers
thought that we should be able to use a ButtonGroup like a Collection,
they would have made ButtonGroup implement Collection. They didn't.
End of story.
But in fact, ButtonGroup fails to keep the expected contract for a
Collection, violating the Principle of Least Astonishment. Leaving
the user-client unwarned when the addition of a JToggleButton to a
ButtonGroup fails, is, it seems to me, lousy software engineering as
well.

I didn't expect it to follow the Collection contract, because it
doesn't implement Collection. I wonder if you fully understand the
idea behind the Java interface. It's a promise of the availability of
certain methods. ButtonGroup isn't a Collection, and therefore hasn't
made a promise.

I agree that it would be nice to get a warning when an add to a
ButtonGroup fails, but I don't think it's anything I've ever checked
for. Why would it fail?
 
K

Kent Paul Dolan

Monique said:
Why would it fail?

Because any "sufficiently complex" piece of software _always_
has a failure mode, for one example of a reason. Because it was
created by failure prone humans, for another. To believe of _any_
piece of software that "it can't fail" flies in the face of the
experience
of every living software engineer, and constitutes "living in a fools'
paradise" and an incredible degree of naive faith tantamount to
unreasoning worship.

IMO based on 44 years of writing software and using software
written by others.

xanthian.
 
J

John C. Bollinger

Kent said:
Monique Y. Mudama wrote:




Because any "sufficiently complex" piece of software _always_
has a failure mode, for one example of a reason. Because it was
created by failure prone humans, for another. To believe of _any_
piece of software that "it can't fail" flies in the face of the
experience
of every living software engineer, and constitutes "living in a fools'
paradise" and an incredible degree of naive faith tantamount to
unreasoning worship.

A more precise question might be "Why would it fail predictably?". Yes,
an OutOfMemoryError might be thrown. Some RuntimeException might be
thrown, even though none are documented. The VM might crash with some
internal error. How do you propose ButtonGroup.add() should handle any
of these conditions other than simply allowing them to occur? They are
all manifestations of bugs or system conditions outside the scope of
ButtonGroup, equally applicable to any method; do you suggest that every
method should document an exhaustive list of such potential problems?
There are no failure conditions /that ButtonGroup is prepared to
detect/, so it is not useful to ButtonGroup to declare a mechanism to
notify clients of a failure.
 
K

Kent Paul Dolan

John said:
There are no failure conditions /that ButtonGroup
is prepared to detect/

You seem to suffer from the same confidence in your
own omniscience as does/did Monique. You cannot,
_possibly_, _know_ that your statement is true, and
in the case, since ButtonGroup implements its
Collection-ness internally with Vector, something
_required_ to honor the Collection-contract to throw
when an add(...) fails, your statement is false.
ButtonGroup is perfectly placed to "detect" that its
add(...) to its internal Vector produced an
exception, and ButtonGroup's "Least Astonishment"
behavior, IMO, would be to recognize that it has an
obligation to forward Collection-contract exceptions
from Vector, and to admit that it does, so that the
user-programmer can extend ButtonGroup similarly
admitting and forwarding such a thrown exception as
part of the implied contract for a Collection, even
one that in hidden fashion, implements its
Collection-ness via a "has-a" Collection
implementation instead of an "is-a" implementation,
_precisely_ the sort of implementation detail that
"encapsulation" is supposed to _hide_ from us
programmers, not to expose as ButtonGroup does by
refusing to be subclassed by something that does a
"throw".

[Your debate trick to generalize something to the
point of ridicule, when such generalization is not a
topic of discussion, but instead a simple single
case is being discussed, is rejected for the idiocy,
dishonesty, and misdirection which it is. Yes,
drinking enough water can kill you. No, that isn't a
useful argument that drinking water is A Bad Thing.]

xanthian.
 
M

Monique Y. Mudama

You seem to suffer from the same confidence in your own omniscience
as does/did Monique.

You seem to suffer from a need to ridicule other people (see your
final paragraph). I'll just go ahead and killfile you now to save
myself the trouble of reading your posts.

And no, it's not because I disagree with you. It's because you're a
jackass.
[Your debate trick to generalize something to the point of ridicule,
when such generalization is not a topic of discussion, but instead a
simple single case is being discussed, is rejected for the idiocy,
dishonesty, and misdirection which it is. Yes, drinking enough water
can kill you. No, that isn't a useful argument that drinking water is
A Bad Thing.]

xanthian.
 
K

Kent Paul Dolan

John said:
A more precise question might be "Why would it fail predictably?".

Sigh. _Lives have been lost_ due to software bugs. Do you really
limit your cases against which you want your software to defend
itself to the failures you can _predict_?

xanthian, like Pontius Pilate, washing his hands of the whole mess.
It's no fun discussing technical stuff with people who get wedged
into a position from which they refuse any longer to _think_, but
instead build a defense of more and more ridiculous stances rather
than admit being in error.

http://www.google.com/search?q=invincible.ignorance+xanthian
 
O

Oliver Wong

Kent Paul Dolan said:
Sigh. _Lives have been lost_ due to software bugs. Do you really
limit your cases against which you want your software to defend
itself to the failures you can _predict_?

There's also an issue of context. This thread started as a discussion of
whether or not javax.swing.ButtonGroup's add method violates an "implied"
contract. Given this topic, one would assume you're not writing software
which may have a direct impact of the life or death of a person.

To quote something you wrote:

<quote>
Your debate trick to generalize something to the
point of ridicule, when such generalization is not a
topic of discussion, but instead a simple single
case is being discussed, is rejected for the idiocy,
dishonesty, and misdirection which it is. Yes,
drinking enough water can kill you. No, that isn't a
useful argument that drinking water is A Bad Thing.
</quote>

Similarly, yes, there is a non-zero probability that JavaDocs for
"add()" might be lying to you, and trusting in it can result in
castastrophic failures leading to the death of hundreds of civilians. No,
that isn't a useful argument that reading the JavaDocs and concentrating on
the interface, rather than the implementation, is A Bad Thing.

- Oliver
 
T

Thomas G. Marshall

Monique Y. Mudama said something like:
You seem to suffer from a need to ridicule other people (see your
final paragraph). I'll just go ahead and killfile you now to save
myself the trouble of reading your posts.

And no, it's not because I disagree with you. It's because you're a
jackass.

I think you're right. The man clearly does not understand what an OO
contract is, and has been attempting to double-talk his way out of admiting
that he was wrong.
 
T

Thomas G. Marshall

Kent Paul Dolan said something like:
You seem to suffer from the same confidence in your
own omniscience as does/did Monique. You cannot,
_possibly_, _know_ that your statement is true, and
in the case, since ButtonGroup implements its
Collection-ness internally with Vector, something
_required_ to honor the Collection-contract to throw
when an add(...) fails, your statement is false.
ButtonGroup is perfectly placed to "detect" that its
add(...) to its internal Vector produced an
exception, and ButtonGroup's "Least Astonishment"
behavior, IMO, would be to recognize that it has an
obligation to forward Collection-contract exceptions
from Vector, and to admit that it does, so that the
user-programmer can extend ButtonGroup similarly
admitting and forwarding such a thrown exception as
part of the implied contract for a Collection, even
one that in hidden fashion, implements its
Collection-ness via a "has-a" Collection
implementation instead of an "is-a" implementation,
_precisely_ the sort of implementation detail that
"encapsulation" is supposed to _hide_ from us
programmers, not to expose as ButtonGroup does by
refusing to be subclassed by something that does a
"throw".

You just embarrassed yourself even more (hard to believe) with this
attempted doubletalk. Pick up a book on OO principals, and learn what
"contract", "is-a", and "has-a" *really* means.

<PLONK>


[Your debate trick to generalize something to the
point of ridicule, when such generalization is not a
topic of discussion, but instead a simple single
case is being discussed, is rejected for the idiocy,
dishonesty, and misdirection which it is. Yes,
drinking enough water can kill you. No, that isn't a
useful argument that drinking water is A Bad Thing.]

xanthian.
 
K

Kent Paul Dolan

There's also an issue of context. This thread started as a discussion of
whether or not javax.swing.ButtonGroup's add method violates an "implied"
contract. Given this topic, one would assume you're not writing software
which may have a direct impact of the life or death of a person.

Muddled thinking.

The issue is comparable to Dijkstra's comments on the
brain damaging impact of COBOL or BASIC programming.

You don't make your coding habits "situational", because
by the time you change situations to ones where those
habits _will_ have a serious negative impact, they are so
ingrained as to be unrecognizable to you, yourself, as bad
habits needing review and revision.

Instead, you make habits, from the first, that will stand you
in good stead in all the cases you can ever reasonably
expect to encounter.

That rule stands not only in programming, but in all of life.

A second, cogent, issue, is that a programmer who could
_predict_ software bugs with assurance, as John suggests
presumably would not bother to put those bugs into source
code form.

It worries me a bit for the future of programming, that so
many programmers suffer from such assurances.

xanthian, wise in the ways of programming humility.

Don't you love the prima donnas who have to make their
"plonk"s public? I have no trouble ceasing to read the
writings of someone who annoys me, without announcing
that choice to the world, and I don't _bother_ using killfile
technology, those few individuals have to burn their names
thoroughly into my brain before I grant them Permanent
Idiot status.
 
O

Oliver Wong

Kent Paul Dolan said:
Muddled thinking.

The issue is comparable to Dijkstra's comments on the
brain damaging impact of COBOL or BASIC programming.

Not everyone agrees with Dijkstra's comments on the brain damaging
impact of COBOL or BASIC programming.
You don't make your coding habits "situational", because
by the time you change situations to ones where those
habits _will_ have a serious negative impact, they are so
ingrained as to be unrecognizable to you, yourself, as bad
habits needing review and revision.

Actually, you *should* make your coding habits situational. Do you
really believe that the programming practices that, say, NASA engineers use
should be the same as the practices that, say, Ubisoft game developers use?
Or vice versa?

On the one hand, you'll have space shuttles crashing into the ground
costing millions of dollars and perhaps some lives as well. On the other,
you'll have games with such unrealistic examples that the games will never
be finished within the time and monetary budgets assigned to them, and the
company will go out of business.
Instead, you make habits, from the first, that will stand you
in good stead in all the cases you can ever reasonably
expect to encounter.

That rule stands not only in programming, but in all of life.

I think people are in disagreement with you about whether or not
ButtonGroup's .add method failing is a case that one can ever reasonably
expect to encounter.
A second, cogent, issue, is that a programmer who could
_predict_ software bugs with assurance, as John suggests
presumably would not bother to put those bugs into source
code form.

I'm not sure how you've infered the above from what John said. Here's
what I see John saying:

<quote>
A more precise question might be "Why would it fail predictably?".
</quote>

I've interpret this as an essentially rhetorical question indicating
that he does not predict it would fail, and that if it does fail, it did so
unpredictably.

[snip]
Don't you love the prima donnas who have to make their
"plonk"s public? I have no trouble ceasing to read the
writings of someone who annoys me, without announcing
that choice to the world, and I don't _bother_ using killfile
technology, those few individuals have to burn their names
thoroughly into my brain before I grant them Permanent
Idiot status.

I don't think the intent is so much to announce to the world, so much as
to announce to the one being plonked. Roedy, for example, has recently said
he temporarily plonked me (not sure if he's undone that yet). I appreciate
him letting me know, so that I don't have to wonder why he has suddenly
mysteriously started ignoring all my messages (some of which were addressed
specifically at him). I can free my mind of those threads and focus on other
conversations from there on.

- Oliver
 
M

Monique Y. Mudama

[cross-posts trimmed]

I think people are in disagreement with you about whether or not
ButtonGroup's .add method failing is a case that one can ever
reasonably expect to encounter.

And if it fails, what are you going to do about it? What's the point
of being able to detect something if there's no reasonable course of
action at that point?
 
K

Kent Paul Dolan

Oh, and by the way, since one consequence of failure
is lots of people potentially dying of thirst (we're
doing water resource planning for three decades out,
in the desert, in this particular application), yes,
life or death _is_ involved, however intangibly and
marginally.
Not everyone agrees with Dijkstra's comments on
the brain damaging impact of COBOL or BASIC
programming.

Well, having written code for money in over twelve
dozen programming languages, including several
incompatible versions of the above two, I'm one who
fully agrees with Dijkstra. Programming should have
been deferred until Pascal came along.
Actually, you *should* make your coding habits
situational. Do you really believe that the
programming practices that, say, NASA engineers
use should be the same as the practices that, say,
Ubisoft game developers use? Or vice versa?

You are confusing "habits" with "requirements".
Using strncat instead of strcat is a "habit", using
DoD 1267a instead of Mad Magazine as programming
guidelines is a "requirement".
I think people are in disagreement with you about
whether or not ButtonGroup's .add method failing
is a case that one can ever reasonably expect to
encounter.

The reasonable man adapts himself to the world;
the unreasonable one persists in trying to adapt
the world to himself. Therefore, all progress
depends on the unreasonable man.
-- George Bernard Shaw

The problem with your statement is precisely the
problem with John's statement: if you could
pre-judge which errors were "reasonable", you could
simply create a checklist for them, and never give
code containing them to the compiler. I'm sure that
giving a list of all "reasonable" errors can be put,
by formal proof, equivalent to Solving the Halting
Problem -- impossible even in theory.
I'm not sure how you've infer[r]ed the above from
what John said. Here's what I see John saying:
<quote>
A more precise question might be "Why would it
fail predictably?".
</quote>

Precisely the phase I quoted above.
I've interpret[ed] this as an essentially
rhetorical question indicating that he does not
predict it would fail, and that if it does fail,
it [would do] so unpredictably.

Umm, and I've interpreted it as an attempt to claim
that ignorance of a counter-example constitutes
proof of a contention, a debased arguing tactic. I
stand by my objection, both to his statement and to
your rewording of it above.
[snip]
Don't you love the prima donnas who have to make
their "plonk"s public?
I don't think the intent is so much to announce to
the world, so much as to announce to the one being
plonked.

Were that the intent, the tone would be helpful
rather than taunting.

FWIW

xanthian.
 
K

Kent Paul Dolan

Monique said:
And if it

[adding a button to a ButtonGroup]
fails, what are you going to do about it? What's
the point of being able to detect something if
there's no reasonable course of action at that
point?

Sigh: read, learn, evolve:

http://www.ccel.org/a/aquinas/summa/FS/FS076.html
http://groups.google.com/groups?q=invincible.ignorance+author:Kent.Paul.Dolan

[Clue 1: the contract of Container is that if you
"add(...)", the thing added _will be there_. Thus,
you "do" whatever you do when you cannot trust that
the button made it into the ButtonGroup, which might
very well be "notify the user of the failure, then
exit with a non-zero exit code". What you _don't_ do
is blunder on in blind ignorance that your
application has become unstable, and behave as if
the add(...) had been successful, causing a cascade
of unintended consequences.

Strangely, that is exactly the situation in which
Sun's choice to make an add(...) failure internal to
ButtonGroup's internal Vector buttons invisible
to the calling client leaves the programmer.

Clue 2: It is going to take roughly _one_ more
question like from you like that one, applying "she
couldn't possibly be that stupid"-level industrial
strength ignorance to an issue, pretending that your
faux ignorance resolves the issue in your favor, and
you will no longer have to worry about _me_ reading
_your_ postings, much less about plonking me.]

xanthian.

By the way, I noticed another infelicity in the Sun
design for ButtonGroup; ButtonGroup needs to be a
descendent of an AbstractButtonGroup that specifies
containment for buttons as a named group, but leaves
the behavior of that group up to the programmer
subclassing AbstractButtonGroup. Having successfully
implemented an AtMostOneButton subclass of
ButtonGroup, I find the existing design increasingly
crippling as I implement an AtMostNButtonsGroup. The
immediate issue that is going to force me to take
two trips around the planet to accomplish a single
step is that to use the

( (DefaultButtonModel) instanceOfACheckBox.getModel() ).setGroup( this
);

I have to buy off on the behavior of ButtonGroup for
"this", and then somehow work around it. How much
nicer it would be if setGroup(...) were a method in
an AbstractButtonGroup that didn't carry the freight
of that "radio button behavior is the only
interesting button group behavior" burden along with
it. Maybe in release 1.6 of the SDK?

[And the reason for wanting to do the above command
is that in a complex environment with lots of button
clusters to which you want to apply varying
behaviors as groups [this application has four
different behaviors: no interaction, radio button
interaction, "at most one button selected"
interaction, and "at most N>1 buttons selected"
interaction, where groups of groups of buttons may
vote on whether a button click does or does not
accomplish a selection of that button"] , you'd like
to be able to navigate easily from the button back
to its containing button group, as well as from the
button group to all of its contained buttons, in
order to implement those behaviors button by button,
button group by button group, and button group
cluster by button group cluster.]

[Umm, and the reason I want an "AtMostNButtonsGroup"
(which I only need for N==2, but the general case
was easier than the specific one) is that my
user-base has a series of image overlays choosable
for a base object, but the software doing the image
processing can't successfully blend more than two
such overlays into a result useful to the user. So,
out of half a dozen possible, 0, 1, or 2 are
allowable, and to bullet-proof the interface, I want
to make that limit a software-enforced one. ]
 

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,763
Messages
2,569,562
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top