While-loop not listening to conditions

I

iMohed

Hello guys. In the code below the while-loop is not listening to the
conditions. Its a recursive method. I have checked in the debuger that
the conditions are met so i dont know realy what the problem is. Maybe
you guys can spot the problem.


private void buildTree(DefaultMutableTreeNode parent, int typeLevelNow)
{


while (typeLevel != typeLevelNow-1) {

String line = sc.nextLine();
String[] s = cleanUp(line);

if (s[0].equals("/")) {
typeLevel = typeLevel--;
} else {
MohedsMutableTreeNode child =
new MohedsMutableTreeNode();
child.setUserObject(s[1]);
child.type = s[2];//.toString());
parent.add(child);
buildTree(child, typeLevel++);

}
}
}

Thanks for any help.
 
E

Eric Sosman

Hello guys. In the code below the while-loop is not listening to the
conditions. Its a recursive method. I have checked in the debuger that
the conditions are met so i dont know realy what the problem is. Maybe
you guys can spot the problem.

It would help if we knew what you were trying to do,
and in what way the code fails to fulfill that purpose.
"Not listening to the conditions" doesn't convey much
to me, I'm afraid.
private void buildTree(DefaultMutableTreeNode parent, int typeLevelNow)
{
while (typeLevel != typeLevelNow-1) {

String line = sc.nextLine();
String[] s = cleanUp(line);

if (s[0].equals("/")) {
typeLevel = typeLevel--;

This looks peculiar. Are you sure you intended to use
the same variable on both sides of the assignment? As it
stands, this statement has no effect: First it decreases
typeLevel by one, then it stores the original value back
into typeLevel again, thus restoring affairs to the same
state as before the statement.
} else {
MohedsMutableTreeNode child =
new MohedsMutableTreeNode();
child.setUserObject(s[1]);
child.type = s[2];//.toString());
parent.add(child);
buildTree(child, typeLevel++);

This also looks peculiar. Note that it guarantees
inequality in the first `while' of the lower-level call:
for example, if typeLevel was 3 to begin with, then the
lower-level method will find typeLevel equal to 4 and
typeLevelNow equal to 3.

Since typeLevel never decreases and can only increase,
and since typeLevelNow is less than typeLevel when the lower-
level method is called, it looks like the `while' loop will
run "forever." Is that what you mean by "not listening to
the conditions?"
 
I

iMohed

     Since typeLevel never decreases and can only increase,
and since typeLevelNow is less than typeLevel when the lower-
level method is called, it looks like the `while' loop will
run "forever."  Is that what you mean by "not listening to
the conditions?"

Yea, that was what i meant. I want the lower level while-loop to have
a guaranteed first run and i see the problem with

typeLevel = typeLevel--;

Im going to try to change it to

typeLevel++;

and see if that resolves the problem. Thanks for your answer.
 
D

Donkey Hottie

(e-mail address removed) wrote in (e-mail address removed):
typeLevel = typeLevel--;

Im going to try to change it to

typeLevel++;

and see if that resolves the problem. Thanks for your answer.

If your purpose is to decrement typeLevel, then typelevel++ does not
serve that purpose.

as

typeLevel = typeLevel--;

does NOT decrement it, you should try simple

typeLevel-- ;

You should study the ++ and -- operators again to refresh your memory.
Seems those are not well understood there in your code.

If typeLevel == 1 then

typeLevel = typeLevel--;

will keep its value as 1.

typeLevel-- ;

will set it to 0, which is what you aparently wanted.

Also, double check this
} else {
MohedsMutableTreeNode child =
new MohedsMutableTreeNode();
child.setUserObject(s[1]);
child.type = s[2];//.toString());
parent.add(child);
buildTree(child, typeLevel++);

if typeLevel = 1 then
buildTree(child, typeLevel++);

will result as buildTree(child, 1);

You might want it to be
buildTree(child, ++typeLevel);

or propably
 
R

Roedy Green

typeLevel = typeLevel--;

This is your problem. You probably meant to say plain typeLevel--;

It is an ambiguous statement the way it is. You both copy the
previous value to typelevel and decrement typelevel. Which takes
precedence? I'd have to put on my language lawyer hat to figure it
out. Don't write that sort of code! I suspect the copy is done last
so it prevails, making this a null statement.

You would have detected this had you run a trace or had you peppered
your loop with debug code to dump out the two crucial variables every
time you expect them to change value or every time you read their
value.

see http://mindprod.com/jgloss/trace.html

In general, try to stick on standard idioms on your loops. As soon as
you go off the beaten track it is so easy to make a mistake.

see http://mindprod.com/jgloss/jcheat.html
--
Roedy Green Canadian Mind Products
http://mindprod.com

"It wasn’t the Exxon Valdez captain’s driving that caused the Alaskan oil spill. It was yours."
~ Greenpeace advertisement New York Times 1990-02-25
 
L

Lew

(e-mail address removed) wrote, quoted or indirectly quoted someone who said :
Roedy said:
This is your problem. You probably meant to say  plain typeLevel--;

It is an ambiguous statement the way it is.  You both copy the

Only psychologically. The language rules are completely
deterministic.
previous value to typelevel and decrement typelevel. Which takes
precedence? I'd have to put on my language lawyer hat to figure it
<http://java.sun.com/docs/books/jls/third_edition/html/
expressions.html#15.7>

out.  Don't write that sort of code!  I suspect the copy is done last
so it prevails, making this a null statement.

Don't suspect, know.
 
R

Roedy Green

Don't suspect, know.

Code that is not clear to the average programmer should be removed
even if its effect is perfectly defined in the JLS. It is, in effect,
a booby trap. In my eyes it is almost as wrong as a syntax error.
I feel similarly about naming caps violations. There is no excuse to
break the standard idioms.

See http://mindprod.com/jgloss/unmain.html

The second reason for avoiding such code is that if there are bugs in
the compiler or the optimiser, that is where bugs are most likely to
show up, since those freaky cases are least likely to be thoroughly
tested. Today compilers are much more reliable. I grew up in the
days when you had to go over the assembler listings to make sure the
compiler was doing its job correctly. It was almost as likely as a
bug in your own code.

We have a philosophical difference. You see code primarily as a way to
communicate with the computer. I see code equally as a way to
communicate with fellow programmers. To you, so long as the computer
understands, there is no problem. To me, I want nearly all other
programmers to understand too, including lazy and inexperienced ones.

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

"It wasn’t the Exxon Valdez captain’s driving that caused the Alaskan oil spill. It was yours."
~ Greenpeace advertisement New York Times 1990-02-25
 
E

Eric Sosman

Roedy said:
Code that is not clear to the average programmer should be removed
even if its effect is perfectly defined in the JLS. It is, in effect,
a booby trap. In my eyes it is almost as wrong as a syntax error.
I feel similarly about naming caps violations. There is no excuse to
break the standard idioms.

I'm with Roedy on this one: The potential for confusion
is too high, and is worth avoiding. It is not unusual to
read and write multiple programming languages over a short
span, and when similar-appearing constructs have vastly
different meanings in those languages it is all too easy to
think Java while looking at C, for example. (The construct
in question in this thread is syntactically valid in all
three of Java, C, and C++, but has well-defined semantics
in only one of them: Identical statements, different meanings,
traps for readers.)

There are two principal readers of code: Compilers and
programmers. When writing, give more heed to the latter.
 
A

Arved Sandstrom

Roedy said:
Code that is not clear to the average programmer should be removed
even if its effect is perfectly defined in the JLS. It is, in effect,
a booby trap. In my eyes it is almost as wrong as a syntax error.
I feel similarly about naming caps violations. There is no excuse to
break the standard idioms.
[ SNIP ]

I agree with you. So does the JLS - in Section 15.7 it says:

"The Java programming language guarantees that the operands of operators
appear to be evaluated in a specific evaluation order, namely, from left
to right.

It is recommended that code not rely crucially on this specification.
Code is usually clearer when each expression contains at most one side
effect, as its outermost operation, and when code does not depend on
exactly which exception arises as a consequence of the left-to-right
evaluation of expressions."

Apart from something like x=x++, the examples provided in Section 15.7
would make me cringe if I saw someone code like that in real life. Now,
the JLS has to cover this stuff, and provide arcane examples, because
it's legal to write this stuff. But the JLS isn't saying that this is
recommended style.

x=x++ made _me_ think, and I'd like to think I'm a pretty good Java
programmer. For starters, I'd never write that, so I might be in the
same boat as you...you think you know what happens, but in order to
figure out for sure you have to check the JLS, maybe run a code snippet
as well.

AHS
 
L

Lew

Roedy said:
Code that is not clear to the average programmer should be removed
even if its effect is perfectly defined in the JLS. It is, in effect,
a booby trap. In my eyes it is almost as wrong as a syntax error.

You have a certain point here.
I feel similarly about naming caps violations. There is no excuse to
break the standard idioms.

See http://mindprod.com/jgloss/unmain.html

The second reason for avoiding such code is that if there are bugs in
the compiler or the optimiser, that is where bugs are most likely to
show up, since those freaky cases are least likely to be thoroughly
tested. Today compilers are much more reliable. I grew up in the

"Those freaky cases" involving operator precedence, first, are not even
slightly "freaky", and, second, the Sun compatibility test suite catches
precedence errors, so this argument does not apply.
days when you had to go over the assembler listings to make sure the
compiler was doing its job correctly. It was almost as likely as a
bug in your own code.

Not the situation with respect to operator precedence in Java or the
determinism of order of evaluation.
We have a philosophical difference. You see code primarily as a way to
communicate with the computer. I see code equally as a way to

Nonsense. I do not see code that way. How presumptuous of you.
communicate with fellow programmers. To you, so long as the computer
understands, there is no problem.

Again, how utterly presumptuous of you to so characterize my thinking. That
is neither my statement, my thought, nor my point. My point, factual and
objective, is that the Java language rules on operator precedence and order of
evaluation are unambiguous. I never said, "so long as the computer
understands, there is no problem", nor implied such a thing.
To me, I want nearly all other
programmers to understand too, including lazy and inexperienced ones.

I want lazy programmers out of the business. I want inexperienced ones to
know at least the most basic facts of the language.

I also did not argue against the use of parentheses or other clarifying
idioms, so you can put the straw man away. I only said that the apparent
ambiguity in the code is strictly psychological, a point you also made.
Therefore we agree on that. I only said that there is no ambiguity in the
meaning of the expression itself, a matter of fact.

I feel that it's important to keep the facts straight. A newbie reading your
post could have been misled by your post into thinking that there is some
ambiguity in the Java language that there isn't. I want other programmers to
understand the facts, too, including inexperienced ones. Your post seriously
risked misleading those inexperienced Java programmers.
 
L

Lew

Arved said:
Roedy said:
Code that is not clear to the average programmer should be removed
even if its effect is perfectly defined in the JLS. It is, in effect,
a booby trap. In my eyes it is almost as wrong as a syntax error.
I feel similarly about naming caps violations. There is no excuse to
break the standard idioms.
[ SNIP ]

I agree with you. So does the JLS - in Section 15.7 it says:

"The Java programming language guarantees that the operands of operators
appear to be evaluated in a specific evaluation order, namely, from left
to right.

It is recommended that code not rely crucially on this specification.
Code is usually clearer when each expression contains at most one side
effect, as its outermost operation, and when code does not depend on
exactly which exception arises as a consequence of the left-to-right
evaluation of expressions."

Apart from something like x=x++, the examples provided in Section 15.7
would make me cringe if I saw someone code like that in real life. Now,
the JLS has to cover this stuff, and provide arcane examples, because
it's legal to write this stuff. But the JLS isn't saying that this is
recommended style.

x=x++ made _me_ think, and I'd like to think I'm a pretty good Java
programmer. For starters, I'd never write that, so I might be in the
same boat as you...you think you know what happens, but in order to
figure out for sure you have to check the JLS, maybe run a code snippet
as well.

I agree with Eric and Arved on this. One should write code that is
psychologically unambiguous, not merely factually so.

Please do not fall into the trap of believing that I thought or said things
that Roedy claimed I thought or said. I can speak for myself. Roedy cannot
speak for me.
 
J

Joshua Cranmer

Roedy said:
It is an ambiguous statement the way it is. You both copy the
previous value to typelevel and decrement typelevel. Which takes
precedence? I'd have to put on my language lawyer hat to figure it
out. Don't write that sort of code! I suspect the copy is done last
so it prevails, making this a null statement.

This is the canonical example of an ISO C/C++ unspecified construct. In
C and C++, it is truly unreliable--when a postfix decrement occurs would
be different for different compilers or possibly even different
architectures for the same compiler. How assignment comes into play
throws yet another wrench into the system.

In Java, expression trees are generally evaluated in the order "lhs,
rhs, expression," and side-effects of expressions will generally occur
immediately after evaluation. So typeLevel is evaluated, decremented,
and then the old value is stored back into typeLevel.
 
L

Lew

Joshua said:
This is the canonical example of an ISO C/C++ unspecified construct. In
C and C++, it is truly unreliable--when a postfix decrement occurs would
be different for different compilers or possibly even different
architectures for the same compiler. How assignment comes into play
throws yet another wrench into the system.

In Java, expression trees are generally evaluated in the order "lhs,
rhs, expression," and side-effects of expressions will generally occur
immediately after evaluation. So typeLevel is evaluated, decremented,
and then the old value is stored back into typeLevel.

See the JLS references cited upthread. As pointed out there, the
statement is computationally unambiguous, although of course it is
psychologically ambiguous.

(And therefore to be avoided. Just in case it needs to be reiterated,
psychologically ambiguous is not recommended.)

It is comforting to know how these statements parse, just in case one
runs across some code that does this sort of thing. Operator
precedence and order of evaluation are among the most fundamental
facets of the Java language and one no competent Java programmer
should find troublesome. When in doubt, refer to the aforementioned
JLS sections for disambiguation. Knowledge is power. (And
conversely, ignorance is weakness.)
 
A

Arne Vajhøj

Lew said:
You have a certain point here.

Yes.

It can be argued that the most brilliant code is code that is so
simple that no maintenance programmer is able to not understand it.
"Those freaky cases" involving operator precedence, first, are not even
slightly "freaky", and, second, the Sun compatibility test suite catches
precedence errors, so this argument does not apply.

Yep.

It is purely a readability issue.

Arne
 
S

Seamus MacRae

Lew said:
It is comforting to know how these statements parse, just in case one
runs across some code that does this sort of thing.

It is comforting just to know that they have unambiguous semantics and
where these are specified. One can always look it up in the JLS
just-in-time. These aren't the bad old days before we had one-click
access to Google during development, when you sometimes had to dig up a
thick manual or even go physically to a library to get information
sometimes. :)

That said, when I read the original post I immediately spotted the line
that was supposed to decrement the loop counter and immediately
recognized it as failing to do so, with very little thought.
Just-in-time lookup of the same thing enough times over the years will
turn it into stuff you just plain remember.

(Conveniently, the JLS is available in two clicks plus four keystrokes
in Firefox, Google Chrome, and, with some tweaks, even Internet
Exploder. Click search box (in Chrome, address bar), type "jls", hit
enter, and click appropriate link. (Currently it's the second hit, but
it might move around a bit over time.) It's available in one click if
you leave a tab parked at it. This is discounting the one-or-more
alt-tabs or one click to switch to the browser, repeated to switch back
to your text editor or IDE. I don't tend to bother, though I do keep a
browser tab parked in Sun's API Javadocs, despite also having in-IDE
access to API docs. Sometimes I want to look up something when the IDE
isn't open or regarding a part not currently used by the code, for
example when deciding what to use to do something before doing anything.)
 
J

Joshua Cranmer

Seamus said:
(Conveniently, the JLS is available in two clicks plus four keystrokes
in Firefox, Google Chrome, and, with some tweaks, even Internet
Exploder.

<Ctrl>-T, j, <Down>, <Enter> for me in Firefox, although I tend to go to
jls instead. In one of my old bookmarks settings, it was just two clicks
(open spec menu, select JLS 3).
 
S

Seamus MacRae

Joshua said:
<Ctrl>-T, j, <Down>, <Enter> for me in Firefox

Heh. That gets me to
http://groups.google.com/group/comp.lang.java.programmer/ which is
probably because I went there recently to get URLs pointing to recent
posts here that anyone could use to read those posts.

, although I tend to go to
jls instead. In one of my old bookmarks settings, it was just two clicks
(open spec menu, select JLS 3).

Alt-B, click if it's "above the fold" in your bookmarks menu in Firefox.

If you bookmark it in Chrome, a few characters typed in the address bar
will probably autocomplete to it, similar to your Ctrl-T, jls, down, enter.

I would still avoid IE. There's a computer I work on from time to time
that has no other web browser -- admin won't allow third-party browsers.
Even leaving aside its bad reputation for instability and security
holes, it's doggone SLOW. It fires up, it starts loading some site
rather than a blank page. Clicking the stop button doesn't make it
instantly abort doing so and wait patiently for user input, oh no, it
will still chug away "connecting" and then loading that site. Sometimes
it will eventually stop, showing either a blank page or "Action
canceled". Sometimes it loads much or all of the page before actually
acknowledging that "stop" was clicked. Of course this machine has a
broadband low-latency connection to the Internet and still it takes ~2
whole minutes to go from double-clicking the little "e" to having the
ability to actually type something into the address bar and go there.

After which it continues to be excruciatingly slow to respond to
anything. It spins for ages on any kind of page load, chugs when
scrolling, chugs when typing anything in, all on a dual-core 2GHz system
with 1GB of RAM. This is a reasonably current version running on an XP
Pro box. Firefox is much faster to become usable and to surf with even
on a Vista box (~10% slower operating system) with comparable hardware,
and Google Chrome is faster still, but not as "full-featured" for sites
that heavily use pdfs, Flash, and the like.

One thing I like about Firefox is the ability to tame the worst evils of
Javascript, preventing sites from interfering with right-clicking and
the like, or hijacking your browser. One nasty site I came across
recently disabled both click-drag selecting text on the page AND the
right-click menu, stupidly. Firefox couldn't re-enable selecting text,
alas, but it did prevent the right-click menu being suppressed, so I
could still "select all". Of course none of their silliness would stop
"view source" or "save page as..." from the main menu, or even "print",
which with a suitable "printer" driver selected could dump the page text
to a file. Apparently those idiots have delusions of copyright granting
them absolute control or something. This is true neither technologically
(I copied an excerpt from their site to use elsewhere despite their
efforts) nor legally (that little excerpt was bright-line fair use).

The other idiots Firefox helps with are advertisers. AdBlock Plus is a
godsend, especially versus ads that don't just sit quietly in their
designated boxes within the page layout until a user deigns to click on
them but, rather, insist upon making themselves impossible to ignore by
being noisy, animating flashily, or (worst of all) scribbling outside of
their boxes and thereby rendering much of the host page unreadable, the
rotten parasites. The one problem with ABP is that somewhere along the
line they lost the feature to "hide" vs. "remove" ads. Now it only
"hide"s them. The difference is that if a page has slow-to-load ads and
tries to detect ad-blocker use, the page still loads slowly with "hide"
and the ad-blocking gets detected with "remove". One former use I had,
removing those site-meter whosits and pixel.gif tracking bugs, is
neutered, since my main reason for removing these wasn't privacy but
speed -- not a one of those exists that doesn't take several full
seconds to load because the server it loads from is overwhelmed with
requests 24/7, and every single one of them seems to be loaded in a
script at the top of the page, which makes nearly the whole page wait to
load until the tracking bug loads (or times out), versus if they'd used
a plain old <img> tag as God intended.

Oh well, at least it isn't the bad old days (circa 1999) when the only
viable choice of browser was Internet Exploder and if the tracking bug
failed to load, Internet Exploder stopped loading the whole page and
told you "The page cannot be displayed..."

Although IE's got a new, nearly as horrible bug: any kind of timeout
loading a page now redirects you to ask.com. If you want to retry you
have to hit back and then refresh instead of just refresh. Worse, the
redirect wipes its memory of form contents so if it was a form
submission, back+click submit won't work, you have to redo everything.
Firefox not only doesn't redirect you like that, it doesn't forget form
contents if you leave and return to a page either, except if the site
designer boneheadedly put a script on the page to wipe the form on page
load. The worst offender for this being Google Blogger's comment
submission page -- it has so many bugs it has to have been ghost-written
for Google by Microsoft. Besides the form blanking on reload even in
browsers that are coded to preserve form contents, the captcha is
unreliable, the form as a whole is unreliable, the page breaks the back
button -- if you go to it from page X you need to hit back twice instead
of once to return to page X -- and last but not least half the time you
go there, start typing, and suddenly the form erases itself about five
seconds later. I think the latter two bugs are caused by some bug that
makes the page reload all by itself randomly sometimes. At least it
doesn't go into a reload loop; that would have made it completely
unusable, since the form would keep blanking and the captcha keep
changing faster than you could fill everything in and submit it.

Long digression from Java; sorry. Upshot: for God's sake don't use IE!
 

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,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top