This week's book giveaway is in the Reactive Progamming forum.
We're giving away four copies of Reactive Streams in Java: Concurrency with RxJava, Reactor, and Akka Streams and have Adam Davis on-line!
See this thread for details.
Win a copy of Reactive Streams in Java: Concurrency with RxJava, Reactor, and Akka Streams this week in the Reactive Progamming forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Liutauras Vilda
  • Junilu Lacar
  • Jeanne Boyarsky
  • Bear Bibeault
Sheriffs:
  • Knute Snortum
  • Tim Cooke
  • Devaka Cooray
Saloon Keepers:
  • Ron McLeod
  • Stephan van Hulst
  • Tim Moores
  • Tim Holloway
  • Carey Brown
Bartenders:
  • Piet Souris
  • Frits Walraven
  • Ganesh Patekar

Understanding the scope rules of inner and outer looping

 
Greenhorn
Posts: 26
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I came across something I haven't seen before in my text book, the keywords INNER and OUTER.
Here's the code:

And based on the output, I have a few questions:

Since line 10 doesn't give any compilation errors regarding i, does this mean that everything in an outer loop have scope over everything in an inner loop in Java?

Based on the output from line 13, why is it possible for an inner loop to break twice? I thought breaking also meant exiting.

Finally, why are the x and y final values different? What would it take to make y have a final value of 12?
 
Marshal
Posts: 65782
250
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
They aren't keywords, but identifiers. The construct XYZ: is called a label. I thought labels were usually written in lower‑case. That suggests you have either got labelled break; or labelled continue; somewhere. Those labels are the equivalent of a goto XYZ;, which violates the concepts of structured programming, and which are never necessary. Bruce Eckel in Thinking in Java (2e, 2006) says that labelled break; is a backward goto rather than a forward goto, which makes it less serious than a forward goto. So there are different opinions about it.
That code has some really bad features. Did you copy it exactly? Please always tell is the full details of the book, including page number, so we can assess it for ourselves and so as to reduce copyright problems.
Don't declare two variables on the same line. Don't write two statements on the same line. Line 10 is really two lines. The variable x is in scope from line 7 to the end of the method and i is in scope for the whole of the loop starting line 8. The i in line 27 is a fresh variable.
I shall leave you to count the values of all those ints as you go through your loops; they look even more complicated than anything out of a cert exam practice book. Whenever x exceeds 10 in line 14, you break out of the loop starting at the INNER: label, and you don't re‑enter that loop (unless a surrounding loop causes it to start again). The label is applied to the same loop the break; is in, so you won't see any difference if you change break INNER; to plain simple break; Since the outer loop isn't broken out of, that keeps running and you get, “breaking INNER,” printed twice.
I shall leave you to work out how to get y to 12. That code is complicated enough without anybody actually trying to understand it.
 
Sam Peterson
Greenhorn
Posts: 26
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:That code has some really bad features. Did you copy it exactly? Please always tell is the full details of the book, including page number, so we can assess it for ourselves and so as to reduce copyright problems.


Jeanne Boyarsky and Scott Selikoff, OCA Java SE 8 Programmer I Study Guide, Introduction-page xxxv, problem 11

Oracle can be cruel. I refuse to assume that I won't see crap like this on the exam.
 
Campbell Ritchie
Marshal
Posts: 65782
250
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Cert exams often contain badly‑written code for candidates to tease apart, so cert books have to show similarly bad examples. I suspect that is worse than you will see in the real exam, since there is no point in showing examples easier than the real question.
 
Rancher
Posts: 3369
31
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Regarding dealing with badly written code, or code that doesn't fit your preferred standards: this isn't just a case of Oracle being difficult.  In real life, we may often find badly written code, perhaps written by someone else who is no longer with the company, but still someone has to fix something about the code they wrote.  Sometimes it turns out the badly written code came from you. . Either way, you may need to deal with it.

That said, I don't think I have ever seen a statement label in code where I've been working.  Ever.  Seems like that's a part of Java that never really got used much, "in the wild".  But I'm sure somewhere, there's a company filled with code that uses labeled break and continue statements.  It's a legal part of the language, whether we like it or not.

Sam Peterson wrote:Finally, why are the x and y final values different? What would it take to make y have a final value of 12?


There are numerous differences between the two sections of code.  Why would you expect the results to be the same?  If you make the two sections the same, you will get the same results.  They're different, and give different results.  There isn't really a single short explanation, other than to step through the results of each part of the code execution.

However, if for some reason you just want to see y = 12, try changing line 26 from

to
 
Saloon Keeper
Posts: 21128
131
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have used labelled loops. VERY rarely, though. And I've always used lower-case labels. Full uppercase, by convention, is what you use for manifest constants. And in Java, not always even then. It's a carry-over from the C programming language.

If you've got a really complex loop structure and you need to bail immediately, but not via an Exception, a labelled loop can save you from having to write some really convoluted skip-over conditionals, making for smaller, simpler code.

But if at all possible, it's better to construct the logic in question so that you don't have that level of complexity to begin with. While a "break my_label" statement may be easier to understand on the whole than its goto-less equivalent, it's so rarely done that some inheritors of the code may get confused at the use of such an odd bird.

Incidentally, my favorite loop label is "loop" and the most common usage I have is like this:

As you can see, perhaps "inner_loop" would be an even better label, but since there are limits to my malice, "break loop" is good enough. Although it does look enough like a keyword clause to risk puzzling someone.
 
Sheriff
Posts: 6266
167
Eclipse IDE Postgres Database VI Editor Chrome Java Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Is the label needed in the above code?  I believe the break will only break the inner loop, not the outer.
 
Marshal
Posts: 14039
234
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Knute Snortum wrote:Is the label needed in the above code?  I believe the break will only break the inner loop, not the outer.


Looks like there's assumed to be some non-trivial processing being done before and after the if-then-break statement so yeah, it would be needed.

That's still smelly to me though and I'd rather pull that inner loop out to its own method and return from it instead. At least that makes the outer loop clearer. The biggest object most people will have to that, in my experience, is with a tendency to optimize with their gut saying "Well, a method call will just slow this down" which I think is bull in most cases anyway, unless it can quantitatively be proven by profiling, not gut checking.
 
Knute Snortum
Sheriff
Posts: 6266
167
Eclipse IDE Postgres Database VI Editor Chrome Java Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Junilu Lacar wrote:

Knute Snortum wrote:Is the label needed in the above code?  I believe the break will only break the inner loop, not the outer.


Looks like there's assumed to be some non-trivial processing being done before and after the if-then-break statement so yeah, it would be needed.


Needed for clarity or needed by the language?  I'm having trouble imagining any code, trivial or not, affecting the way break works inside a loop.  But then, maybe my imagination is not good enough. ;)
 
Junilu Lacar
Marshal
Posts: 14039
234
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Knute Snortum wrote:

Junilu Lacar wrote:

Knute Snortum wrote:Is the label needed in the above code?  I believe the break will only break the inner loop, not the outer.


Looks like there's assumed to be some non-trivial processing being done before and after the if-then-break statement so yeah, it would be needed.


Needed for clarity or needed by the language?


Neither. If you're saying the label isn't needed because there are other ways to code the logic so that the use of labels and break or continue statements are avoided, I agree. But if you want to keep the structure that TH showed, then yes, you need that break. And I think your imagination is fine
 
Tim Holloway
Saloon Keeper
Posts: 21128
131
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Junilu Lacar wrote:

Knute Snortum wrote:Is the label needed in the above code?  I believe the break will only break the inner loop, not the outer.


Looks like there's assumed to be some non-trivial processing being done before and after the if-then-break statement so yeah, it would be needed.

That's still smelly to me though and I'd rather pull that inner loop out to its own method and return from it instead. At least that makes the outer loop clearer. The biggest object most people will have to that, in my experience, is with a tendency to optimize with their gut saying "Well, a method call will just slow this down" which I think is bull in most cases anyway, unless it can quantitatively be proven by profiling, not gut checking.



Actually, I would also depend on the optimizer to inline a separate inner-loop method. When it makes sense. As I said, I don't do this sort of thing often. But when I do, I at least think that there is a benefit of some sort in keeping it all together.

Plus, last time I needed to to this, recent additions to the language such as lambdas didn't exist.
 
Junilu Lacar
Marshal
Posts: 14039
234
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Tim Holloway wrote:Actually, I would also depend on the optimizer to inline a separate inner-loop method. When it makes sense.


Exactly what I do as well. In fact, I probably assume more often than not that anything I extract to a private method can easily be identified by the optimizing compiler as something that can be inlined.
 
Mike Simmons
Rancher
Posts: 3369
31
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Junilu Lacar wrote:

Knute Snortum wrote:

Junilu Lacar wrote:

Knute Snortum wrote:Is the label needed in the above code?  I believe the break will only break the inner loop, not the outer.


Looks like there's assumed to be some non-trivial processing being done before and after the if-then-break statement so yeah, it would be needed.


Needed for clarity or needed by the language?


Neither. If you're saying the label isn't needed because there are other ways to code the logic so that the use of labels and break or continue statements are avoided, I agree. But if you want to keep the structure that TH showed, then yes, you need that break. And I think your imagination is fine


You may need a break, yes, but does it need to be a labeled break?  In the code Tim showed, in terms of program execution, it doesn't.  You could replace "break loop;" with "break;" and it would function exactly the same, breaking out of the innermost enclosing loop.  We might want a label for clarity, but it's not needed here for functionality.  And even for clarity, the problem of course is that it becomes less readable simply because may people are not used to seeing labeled breaks.  Even if they should be.

We can imagine an alternate version where the label is necessary, either because we need to exit the outer loop, or if the if statement had been a switch statement.  Then the labeled break becomes necessary.  Or, you refactor to make the outer loop a method, and then the break is replaced with a return.  I think that's the sort of thing I've usually done to avoid needing a labeled break - but I agree there are some situations where that's not as good an option.  E.g. if you want to share several local variables inside and outside the loop, then extracting a method may not work because you can't return multiple values.  And then you consider if you need to introduce a new small class to encapsulate the multiple variables... but it might be easier to just use a labeled break, I agree.
 
Junilu Lacar
Marshal
Posts: 14039
234
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So much nuance. You guys are right, the label is not needed if the desire is to just break out of the inner loop but not from the outer loop.

See how relevant Dijkstra's assertion about GOTO still is.
 
Mike Simmons
Rancher
Posts: 3369
31
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Strong agreement with Tim and Junilu on the last point.  I pretty much always decide whether or how to extract a method based on readability only, and trust the JVM to do the right thing if there's a problem with performance.
 
Tim Holloway
Saloon Keeper
Posts: 21128
131
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Junilu Lacar wrote:So much nuance. You guys are right, the label is not needed if the desire is to just break out of the inner loop but not from the outer loop.

See how relevant Dijkstra's assertion about GOTO still is.



Yeah. I was reconstructing from memory, so the illustrated case is probably not what I was actually doing.

You cannot BELIEVE how much I appreciated it when structured programming support entered mainstream programming languages. I'm ancient enough to have started on FORTRAN (sic), COBOL, and assembly language, none of which were originally equipped with decent goto-less options. Although I did once support a COBOL program which managed to nest IF statements to the point where the initial "IF" and the full-stop marker that ends COBOL statements were separated by more than a full page of code (66 lines). And in FORTRAN IV, statement labels weren't even allowed to be meaningful names, just arbitrary numbers.
 
Space pants. Tiny ad:
Java file APIs (DOC, XLS, PDF, and many more)
https://products.aspose.com/total/java
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!