Holy boop: goto for Java

D

Daniel Pitts

Lew said:
I have never seen a use of Java's labeled 'break' or 'continue'
outside of tutorials and examples, though.
I've very occasionally found them useful, but they are on the list of things
I wouldn't miss if they were gone. Others: [snip]
* Local classes (i.e. named classes defined inside a method)
Holy unknown construct Batman! I had no idea this was possible, and I
definitely would have used in in certain places!

Specifically, for callbacks where I need to set values to be retrieved
after the call.


void doSomething(SomethingSomething something) {
class MyCallback implements SomeCallbackInterface {
int calls;
boolean error;


public void somethingCalled() { ++calls; }
public void somethingErrored() { error = true; }
}

MyCallback cb = new MyCallback();

something.doSomethingwith(cb);
if (error) {
handleError();
}
if (cb.calls < 100) { smallBatch(); } else { largeBatch(); }
}


For example.

I have often instead created private static inner classes for this
purpose, but that pollutes the class IMO.
 
R

Robert Klemme

public void processResources(String ... resourceNames)
{
....

I'd rather

public void processResources(String ... resourceNames)
{
for (String name : resourceNames)
{
try
{
final BufferedReader br =
new BufferedReader(new FileReader(name));
try
{
doSomething(br);
reportComplete(name);
}
catch(IOException exc)
{
logger.error("Issue while processing "+ name, exc);
}
finally
{
close(br);
}
}
catch(FileNotFoundException exc)
{
logger.error("Cannot find "+ name, exc);
}
}
}

close() is a static helper method which catches IOException and reports it.

In other words, I try to place the catch block at the end of a logical
section and use try catch to only execute some commands in absence of
error. The exception will make the continue superfluous. The advantage
in my eyes is that you can easily follow the regular flow and have error
handling concentrated in one place. I sometimes even refactor out
methods so I can have this catch at the end idiom.

In a more realistic example I'd probably extract parts of this into a
method (likely the inner try catch finally).

Kind regards

robert
 
D

Daniel Pitts

Gene said:
Robert said:
Mike Schilling wrote:
* Do-while. It seems almost never to be what's needed. Though I do quite
often need

while(true)
{
stuff
if (condition)
{
break;
}
more stuff
}

Interesting: I cannot remember having needed this. While I do remember
using do {} while. What use cases do you have for the construct above?

In the sense that there are other ways one can do this, no, you
do not need this. It can be useful if you have multiple tests in that
loop, especially multiple tests that cannot be combined. An example
of this would be a body of:
process first piece
if error
break or continue as needed
process middle piece
if error
break or continue as needed
process last piece

[snip]

public void processResources(String ... resourceNames)
{
for (String name : resourceNames)
{
BufferedReader br;
try
{
br = new BufferedReader(new FileReader(name));
FWIW, this is a potential resource leak (think OOM on the "new
BufferedReader")
}
catch(FileNotFoundException exc)
{
logger.error("Cannot find "+ name, exc);
continue;
}
assert br != null; // and is valid
br is never assigned null, you could make br final. I think it *should*
be final.
try
{
doSomething(br);
}
finally
{
try
{
br.close();
}
catch(IOException exc)
{
logger.error("Cannot close "+ name, exc);
continue;
}
}
reportComplete(name);
}
}

(Not using try-with-resources here, in order to illustrate the idiom.)

Hmm, a failure to close causes a resource processing not to be complete?
 
A

Arved Sandstrom

I am not religious about break / continue (although I use it extremely seldom, I am more likely to use "return" inside a loop). But I disagree about your general statement about little auxiliary methods usually not improving readability. It all depends on the specific case, of course, but giving a short part of an algorithm a name (with the option to have a place to put JavaDoc) often helps readability in my experience.

Kind regards

robert

When I mean "little", I mean little - like 2 or 3 lines little. Based on
the "no exceptions NEVER use labeled break/continue" language that I've
seen in threads on this subject, and the invariable suggestion of using
extracted helper methods instead, this *inevitably* means that many of
these helper methods will be that small. After all, the body of such a
method would be whatever the body of the inner loop is, and in my
experience that's often small.

I am not super-dogmatic about many things, but one thing I will not
yield ground on is the readability hit of little (1-3 lines of Java)
methods. *Sometimes*, with a well-chosen name, and general
applicability, these are perfectly OK. But these idiots in these threads
I allude to are talking about extracting all code in an inner loop, if
it would require a conditional break or continue, robotically making a
method out of it - even if that outer loop is the only caller - without
any intelligent thought whatsoever.

Can you imagine what kind of names such methods might have? How about
"innerLoopStuff()"?

AHS
 
D

Daniel Pitts

When I mean "little", I mean little - like 2 or 3 lines little. Based on
the "no exceptions NEVER use labeled break/continue" language that I've
seen in threads on this subject, and the invariable suggestion of using
extracted helper methods instead, this *inevitably* means that many of
these helper methods will be that small. After all, the body of such a
method would be whatever the body of the inner loop is, and in my
experience that's often small.

I am not super-dogmatic about many things, but one thing I will not
yield ground on is the readability hit of little (1-3 lines of Java)
methods. *Sometimes*, with a well-chosen name, and general
applicability, these are perfectly OK. But these idiots in these threads
I allude to are talking about extracting all code in an inner loop, if
it would require a conditional break or continue, robotically making a
method out of it

No need to call me an idiot. Actually, I don't advocate "extracting all
code in an inner loop, if it would require a conditional break or
continue". I advocate distinct intuitive steps into simple methods,
always, unless you have a specific reason not to. A good reason, not
just any reason.

Many experts in the field of software design agree. I learned this
practice directly from Martin Fowler as a matter of fact, in a training
session he did on TDD at my company.
- even if that outer loop is the only caller -
Who calls a method is irrelevant to only value of such a method, unless
the number of callers is zero of course.
without any intelligent thought whatsoever.
Intelligent thought is always required, for all software design. The
problem is when people do things by guessing.
Can you imagine what kind of names such methods might have? How about
"innerLoopStuff()"?
It depends on the loop. How about instead "processNextStuff()" (where
stuff is replaced with a meaningful name).

I'm not going to say "It must always be done!" but I will say that when
done *right*, it will improve the maintainability of the code base
significantly.

Thanks,
Daniel
Yet Another Idiot Apparently.
 
G

Gene Wirchenko

Personally, I find this sort of stuff to be very unreadable. If
it is used multiple times, it is not quite so bad. If it is used but
once, it is a disruption to following the caller.

There is also context to consider. I have sometimes considered
moving some short, common code to subroutines to find that by the time
I re-established the context in the subroutine, the subroutine's code
would be longer than having the code in the caller.

That is extreme.
No need to call me an idiot. Actually, I don't advocate "extracting all
code in an inner loop, if it would require a conditional break or
continue". I advocate distinct intuitive steps into simple methods,
always, unless you have a specific reason not to. A good reason, not
just any reason.

You are talking past each other. He is not talking about
intuitive steps, but just automatic "methodising" of code.
Many experts in the field of software design agree. I learned this
practice directly from Martin Fowler as a matter of fact, in a training
session he did on TDD at my company.

Who calls a method is irrelevant to only value of such a method, unless
the number of callers is zero of course.

If it is only one, in-line might be better.
Intelligent thought is always required, for all software design. The
problem is when people do things by guessing.

Or by manifesto which is much the same.
It depends on the loop. How about instead "processNextStuff()" (where
stuff is replaced with a meaningful name).

innerLoopStuff2(), innerLoopStuff3(), ... ?
I'm not going to say "It must always be done!" but I will say that when
done *right*, it will improve the maintainability of the code base
significantly.

But then it probably would be done as the code is written,
because it is a sensible -- what you called "intuitive" above --
design.

I like my code to tell a story at one level of abstraction. It
makes it easier to follow the logic. The high-level code is all in
one sequence. With this, I can skip the lower-level logic most of the
time. If I need to adjust the higher-level logic, it is a good sign
when I do not have to concern myself much with the lower-level logic
(because what I came up with for it is still what is needed).
Thanks,
Daniel
Yet Another Idiot Apparently.

Nope. You are too thoughtful for that.

Sincerely,

Gene Wirchenko
 
L

Lew

FWIW, this is a potential resource leak (think OOM on the "new
BufferedReader")

OOM is not a resource leak, it's a program crash.

I generally don't handle 'Error's. (Except when I do.)
If the OOM happens here as you suggest, well, what Leif said.
br is never assigned null, you could make br final. I think it *should*
be final.

Yes. Actually, in real code with this idiom I do make it final. Good catch.
Hmm, a failure to close causes a resource processing not to be complete?

You read too much into the method names.

It's a pattern. I do not claim the names and all are useful in real life, only for pedagogy.

Use better names if these make you twitch.
 
G

Gene Wirchenko

Hmm, but with that argument you must put everything in one method - what
you clearly do not do as your later comments show. :)

NO! Pulling some code out to make it a method that is called
ONLY ONCE is what I object to. (I might do it if there is
clearly-delineated functionality that could be useful again (but just
happens to be needed but once when it written)). I will not do it for
some manifesto.
Right. Or if argument lists get too long that is also a good sign that
something is wrong.

Yes. I should have included length of calling sequence.
That's an interesting way to put it. And it hits the nail on the head.

I hit on it several years ago. Many of my programs or large
segments have one story with the rest of the methods/subroutines
supporting it. A consequence of this is that some of my methods can
get rather long (ones that tell a story).
Right! That discussion nicely shows why it still needs humans to write
software: the process of cutting algorithms in parts cannot be easily
automated. One reason for that is that we do not write for machines
(which easily cope with the most contrived code as long as it compiles)
but rather for humans - namely the one who comes after us and has to fix
a bug or add a feature.

Which is often us so being nice to the maintenance programmer is
being nice to oneself.

Besides the story paradigm, I also think in terms of program
usefulness. If a program is not very useful, one can write it pretty
much any way one wants as the program is going to get tossed anyway.
If it is useful, then it is going to stick around, and requirements
have a way of changing so the program had better be maintainable. It
can also be difficult to tell whether a program will be useful so why
not just write them all clearly?

Sincerely,

Gene Wirchenko
 
D

Daniel Pitts

NO! Pulling some code out to make it a method that is called
ONLY ONCE is what I object to. (I might do it if there is
clearly-delineated functionality that could be useful again (but just
happens to be needed but once when it written)). I will not do it for
some manifesto.

Code re-usability is the great lie that has become the manifesto, not
pulling out a once-used method.

You don't create a method, or a class, or any other abstraction just so
that it is reusable. You create abstractions so that it is easier to
manipulate the software without breaking it. Yes, if you have the same
code in 3 places, pulling it into a method creates "reuse", but the
reason you reuse the code is so that changes to it appear *everywhere*
they should. Otherwise copy and paste would be an acceptable method of
code reuse. And its not.

My philosophy on designing software is make it correct, make it simple,
make it pretty, make it fast. Usually (but granted not always) if you
start from the left, you'll end up at the right much easier than
starting at the right and going left.

If making it simple or pretty involves pulling out a simple one-line
method that isn't used but once, then so be it. If pulling that method
out makes it uglier, then I don't do it.
 
G

Gene Wirchenko

Code re-usability is the great lie that has become the manifesto, not
pulling out a once-used method.

You don't create a method, or a class, or any other abstraction just so
that it is reusable. You create abstractions so that it is easier to
manipulate the software without breaking it. Yes, if you have the same
code in 3 places, pulling it into a method creates "reuse", but the
reason you reuse the code is so that changes to it appear *everywhere*
they should. Otherwise copy and paste would be an acceptable method of
code reuse. And its not.

My philosophy on designing software is make it correct, make it simple,
make it pretty, make it fast. Usually (but granted not always) if you
start from the left, you'll end up at the right much easier than
starting at the right and going left.

If making it simple or pretty involves pulling out a simple one-line
method that isn't used but once, then so be it. If pulling that method
out makes it uglier, then I don't do it.

We are in violent agreement.

Sincerely,

Gene Wirchenko
 
R

Robert Klemme

Which is often us so being nice to the maintenance programmer is
being nice to oneself.

That's a nice side effect - and a motivating argument which helps the
selfish. :)
Besides the story paradigm, I also think in terms of program
usefulness. If a program is not very useful, one can write it pretty
much any way one wants as the program is going to get tossed anyway.
If it is useful, then it is going to stick around, and requirements
have a way of changing so the program had better be maintainable. It
can also be difficult to tell whether a program will be useful so why
not just write them all clearly?

I suspect often the answer to that question is: because the author did
not understand the problem or the program or programming itself clearly.
The other big reason is carelessness, often increased by tight
schedules. Deadlines seem to make people nervous and trying to take
short circuits. But it will cost - sooner or later.

Kind regards

robert
 
E

Eric Sosman

That's a nice side effect - and a motivating argument which helps the
selfish. :)


I suspect often the answer to that question is: because the author did
not understand the problem or the program or programming itself clearly.
The other big reason is carelessness, often increased by tight
schedules. Deadlines seem to make people nervous and trying to take
short circuits. But it will cost - sooner or later.

In my experience, it is often the case that shortcuts extract
their price sooner rather than later, in the form of more testing
and debugging time (and if you don't pay that price, you pay the
still higher price of more and nastier bugs, more support headaches,
and more patch releases).

Not always, mind, but often.
 
G

Gene Wirchenko

Enlightened selfishness.

I would go with the latter but not the former. One can still
program clearly even if one is unsure of exactly what to do, but those
who can not program are very good at messing up.
Yup.

In my experience, it is often the case that shortcuts extract
their price sooner rather than later, in the form of more testing
and debugging time (and if you don't pay that price, you pay the
still higher price of more and nastier bugs, more support headaches,
and more patch releases).

Not always, mind, but often.

Not always, so those who want to justify shortcuts can do so. Try
pointing out that the same arguments apply to playing Russian
roulette, and invite them to play.

Sincerely,

Gene Wirchenko
 
A

Arved Sandstrom

Code re-usability is the great lie that has become the manifesto, not
pulling out a once-used method.

You don't create a method, or a class, or any other abstraction just so
that it is reusable. You create abstractions so that it is easier to
manipulate the software without breaking it. Yes, if you have the same
code in 3 places, pulling it into a method creates "reuse", but the
reason you reuse the code is so that changes to it appear *everywhere*
they should. Otherwise copy and paste would be an acceptable method of
code reuse. And its not.

My philosophy on designing software is make it correct, make it simple,
make it pretty, make it fast. Usually (but granted not always) if you
start from the left, you'll end up at the right much easier than
starting at the right and going left.

If making it simple or pretty involves pulling out a simple one-line
method that isn't used but once, then so be it. If pulling that method
out makes it uglier, then I don't do it.

We're pretty much in agreement. I don't think my reply to an earlier
post of yours, sardonically characterizing yourself as an idiot, made it
to this NG: in that reply I indicated that Gene actually captured my
thinking well, and that you and I were discussing at cross-purposes.

My main objection to kneejerk "Extract As Method", to avoid things like
loop labels (but really kneejerk for any reason), is maintenance - by me
later, or by other people. I also agree that re-use isn't usually a
major factor. For me it's maintenance, IOW readability. If I have to
keep jumping, even with the aid of an IDE, from one spot to another to
track down code chunks, it degrades my capability to put code in
perspective, and it wastes my time.

On another note, copy and paste can be perfectly OK. It's not OK if you
now have to maintain business rules or constants or suchlike in several
spots, or if it's an intricate algorithm, but otherwise it can
frequently be the right thing to do, again informed by maintenance
considerations. Copy 'n' paste is wrong mainly when the people doing it
don't understand what, and why, they are doing it.

AHS
 
L

Lew

Arved Sandstrom wrote:
[snip]
My main objection to kneejerk "Extract As Method", to avoid things like
loop labels (but really kneejerk for any reason), is maintenance - by me
later, or by other people. I also agree that re-use isn't usually a
major factor. For me it's maintenance, IOW readability. If I have to
keep jumping, even with the aid of an IDE, from one spot to another to
track down code chunks, it degrades my capability to put code in
perspective, and it wastes my time.

On another note, copy and paste can be perfectly OK. It's not OK if you
now have to maintain business rules or constants or suchlike in several
spots, or if it's an intricate algorithm, but otherwise it can
frequently be the right thing to do, again informed by maintenance
considerations. Copy 'n' paste is wrong mainly when the people doing it
don't understand what, and why, they are doing it.

+1
 
C

Chris Riesbeck

One test that I use in this sort of situation is to try to think of a
name for the potential extracted method. If there is a good, clear,
simple name, I make a method. If not, I'm more likely to leave it in place.

Patricia

I've always liked the way someone long ago put it on this group or maybe
comp.lang.lisp: "You should define a function if the call to it is
clearer than the code it replaces."
 
G

Gene Wirchenko

On 7/22/2012 8:37 AM, Patricia Shanahan wrote:
[snip]
One test that I use in this sort of situation is to try to think of a
name for the potential extracted method. If there is a good, clear,
simple name, I make a method. If not, I'm more likely to leave it in place.

That is the first test. If there is no GCS name, either it does
not need extracting or you have a bad design that should be addressed.
I've always liked the way someone long ago put it on this group or maybe
comp.lang.lisp: "You should define a function if the call to it is
clearer than the code it replaces."

I would add that if the code is repeated, then break it out even
if it is a bit more complicated. (I do not like cut-and-paste
programming.)

Sincerely,

Gene Wirchenko
 
Joined
Aug 8, 2012
Messages
1
Reaction score
0
Just looking for an extended answer to an earlier question (strings in a
case-switch statement), I found this on Joe Darcy's blog:

"Summary

"Provide the benefits of the time-testing goto control structure to Java
programs. The Java language has a history of adding new control
structures over time, the assert statement in 1.4, the enhanced for-loop
in 1.5,and try-with-resources in 7. Having support for goto is
long-overdue and simple to implement since the JVM already has goto
instructions."

<https://blogs.oracle.com/darcy/entry/upcoming_jep>

Holy booping bat boop Batman!


Sheeit. That Oracle blog looked so legit. Until I saw the date!

<http://www.javagoto.com>

Not an April Fools joke!
 

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

Forum statistics

Threads
473,770
Messages
2,569,586
Members
45,097
Latest member
RayE496148

Latest Threads

Top