question?

C

cbossens73

I think most posters in this thread have avoided the question.

Several people suggested that usually throwing an
IllegalArgumentException
was the way go. That's not avoiding the question. It's a very
reasonable
answer, especially for people that value design by contract
(precondition,
postcondition, invariant checking, etc.).

I'm a big fan of strict specifications/requirements and "failing
early"
when they aren't met.

There are two competing goals: one is to have a single exit, which makes
it easier to do cleanup or other things that need to happen every time
the method ends. The other is to keep the code simpler and
avoid too much nesting

A case could be made that having multiple exit is
making the code *harder* to understand because it makes
it spaghetti code.

Multiple exits are glorified gotos, just like using exception
for flow control.
 
L

Lew

These are not called "function" in Java but

Methods actually are often called "functions" in Java, informally, and that
doesn't affect use of the word in a method name anyway.
 
A

Arved Sandstrom

Several people suggested that usually throwing an
IllegalArgumentException
was the way go. That's not avoiding the question. It's a very
reasonable
answer, especially for people that value design by contract
(precondition,
postcondition, invariant checking, etc.).

I'm a big fan of strict specifications/requirements and "failing
early"
when they aren't met.



A case could be made that having multiple exit is
making the code *harder* to understand because it makes
it spaghetti code.

If because of conditional logic you have 5 different ways in which the
final value of a return might be set, you can either:

(1) have a result variable that is declared at the start, and which is
then set in one of 5 different spots, and is finally returned from one
spot; or

(2) have no initial result value declaration, and have 5 return
statements, each one immediately after a value is determined.

Approach #1 is hardly easier to understand than approach #2. All that's
easier to understand is the location of the return statement. You still
don't have any easier understanding of what path, in a given situation,
will actually set the return value.
Multiple exits are glorified gotos, just like using exception
for flow control.

You can only think that if you are bound to the notion that there must
be a single exit, and that each exit in a set of multiple exits is
somehow conceptually an invisible goto to this notional single exit.

Personally I think multiple exits can simplify the understanding of code.

AHS
 
C

cbossens73

Which is bad why? Even assuming you are correct.

As much as I loved JMP when programming in assembly,
I consider goto's to be an abomination in a well
written OO program (I don't dispute the usefulness
of the Java goto bytecode, I say it has no place
in OOP).

Not hardly.

"exceptions used for flow control are glorified gotos",
which is what I meant in case that wasn't clear.

"Exceptions (in Java and C++) are like non-local goto statements."

http://c2.com/cgi/wiki?DontUseExceptionsForFlowControl

Joshua Bloch takes the exact same stance.

So does Bruce Eeckel.

There are entire frameworks -- and very succesful ones --
like Spring, that consider that forcing users to do
goto-catch programming is a very bad practice.

Spring doesn't unnecessarily forces you to goto-catch
checked exceptions.

I think I started admitting that catching checked
exception was basically GOTO programming upon
reading this article (that took me a while to
find back):

"When I find myself using exceptions to outline
"alternative paths of of execution...
"I need to stop and admit that I'm coding with GOTOs.

From:

http://www.dehora.net/journal/2003/08/checked_exception_still_considered_pointless.html

Re-reading this years after, it's really good
to see that the author laments that he's not
expecting things to change anytime soon, yet
meanwhile frameworks like Spring proved that
there was another way... And in my opinion
the author was right on spot, so were the
Spring guys, so is anyone who says that
using exception for flow control is GOTO
programming.

But that is just an opinion, your entitled
to yours.

To paraphrase a sentence of yours, I suggest
you "try to read" articles on the subject.

(Instead of asking "have you read this?" to
someone here in c.l.j.p. you asked "have you
tried to read this?").

So if you want to *discuss* (instead of posting
your usual, very helpful, one line answers) that
subject, I suggest you "try to read" [sic] articles
on that subject.

Because I surely did and I post more than one line
answers.

Google is your friend and "exceptions" "flow control"
"goto" should be good starting keywords.

But of course you seem so emotionally invested in
making single line quotes and single line answers
showing how smart you are that I don't expect to
hear from you:

"it's an interesting point of view"

Yet for many very smart people it is.
 
L

Lew

As much as I loved JMP when programming in assembly,
I consider goto's to be an abomination in a well
written OO program (I don't dispute the usefulness
of the Java goto bytecode, I say it has no place
in OOP).

I disagree that "multiple exits are glorified gotos". Simply drawing the
analogy doesn't prove that multiple exit points are bad; you have to show what
about 'goto' is bad, and how multiple exit points reflect that badness. You
did neither.

Java has a 'goto' called 'break'. It is carefully renamed to avoid the sort
of prejudice you evince, and restricted so that the bad things about 'goto'
cannot happen, while the useful parts remain.


> [reasons why using exceptions for flow control is like using 'goto']

You misconstrue. I am not in favor of using exceptions for flow control.
It's just that they are so much more complex and costly than 'goto' for that
purpose that the analogy between them is very inexact.
But of course you seem so emotionally invested in
making single line quotes and single line answers
showing how smart you are that I don't expect to
hear from you:

I was taking you seriously until you got personal. How about you avoid the
unnecessary /ad hominem/ attacks, hm?

Your argument that "multiple exits are glorified gotos" was itself a
single-line comment that completely omitted the reasons why 'goto' can be bad,
and how multiple exits reflect that. Cast out the beam in thine own eye
before attacking the mote in mine, brother.
 
A

Arne Vajhøj

Roedy said:
multi-returns are frowned on.

Mostly by people that read a book written by a smart person
that states "X is bad because of Y" and forget everything
about the explanation Y and just consider "X is bad" as
a given.

Arne
 
A

Arne Vajhøj

A case could be made that having multiple exit is
making the code *harder* to understand because it makes
it spaghetti code.

For a method that can not be on one screen, then a conditional
exit in the top can actually make the code more readable.
Multiple exits are glorified gotos, just like using exception
for flow control.

On the contrary. Multiple exit points and goto's to a
single exit point are two different ways of solving the
same problem.


Arne
 
A

Arne Vajhøj

"exceptions used for flow control are glorified gotos",
which is what I meant in case that wasn't clear.

"Exceptions (in Java and C++) are like non-local goto statements."

http://c2.com/cgi/wiki?DontUseExceptionsForFlowControl

Joshua Bloch takes the exact same stance.

So does Bruce Eeckel.

There are entire frameworks -- and very succesful ones --
like Spring, that consider that forcing users to do
goto-catch programming is a very bad practice.

Spring doesn't unnecessarily forces you to goto-catch
checked exceptions.

I think I started admitting that catching checked
exception was basically GOTO programming upon
reading this article (that took me a while to
find back):

"When I find myself using exceptions to outline
"alternative paths of of execution...
"I need to stop and admit that I'm coding with GOTOs.

From:

http://www.dehora.net/journal/2003/08/checked_exception_still_considered_pointless.html

Re-reading this years after, it's really good
to see that the author laments that he's not
expecting things to change anytime soon, yet
meanwhile frameworks like Spring proved that
there was another way... And in my opinion
the author was right on spot, so were the
Spring guys, so is anyone who says that
using exception for flow control is GOTO
programming.

But that is just an opinion, your entitled
to yours.

It should be noted that Lew's opinion is what the design
of Java was based on adn what the majority of Java developers
believe in.

Arne
 
A

Arved Sandstrom

Arne said:
Mostly by people that read a book written by a smart person
that states "X is bad because of Y" and forget everything
about the explanation Y and just consider "X is bad" as
a given.

Arne

With reference to multiple exits most posters who are going to write
about it will probably Google it, and will almost certainly find this by
Bruce Eckel:
http://onthethought.blogspot.com/2004/12/multiple-return-statements.html

There is nothing there to say that multiple exits are bad...unless you
read it the wrong way.

Where this "rule" came from is structured programming, and even there it
was controversial.

In general, if you're going to repeat a nugget of wisdom, say by Eckel
or Bloch or Ambler or McConnell or Meyers or Goetz, please thoroughly
understand the nugget first. And hey, these gentlemen are not perfect -
if you really know your stuff then maybe you're right and one of them is
not.

AHS
 
A

Arne Vajhøj

Arved said:
With reference to multiple exits most posters who are going to write
about it will probably Google it, and will almost certainly find this by
Bruce Eckel:
http://onthethought.blogspot.com/2004/12/multiple-return-statements.html

There is nothing there to say that multiple exits are bad...unless you
read it the wrong way.

Where this "rule" came from is structured programming, and even there it
was controversial.

In general, if you're going to repeat a nugget of wisdom, say by Eckel
or Bloch or Ambler or McConnell or Meyers or Goetz, please thoroughly
understand the nugget first. And hey, these gentlemen are not perfect -
if you really know your stuff then maybe you're right and one of them is
not.

There is a pretty good chance that those gentlemen are correct.

But it is important to understand the context of when something is
bad. Some things are always bad. But most bad things are only bad
in some contexts. 90% or 99% of cases.

Arne
 
J

Joshua Cranmer

Arved said:
In general, if you're going to repeat a nugget of wisdom, say by Eckel
or Bloch or Ambler or McConnell or Meyers or Goetz, please thoroughly
understand the nugget first. And hey, these gentlemen are not perfect -
if you really know your stuff then maybe you're right and one of them is
not.

There are no hard-and-fast rules: in general, every guideline will have
cases where one can and should ignore the proposition at hand.

Take for example the infamous goto statement. If you read Dijkstra's
original letter
(<http://www.cs.utexas.edu/users/EWD/ewd02xx/EWD215.PDF>), you'll notice
that he disliked goto not because it wasn't useful, but because it was
too primitive, much like how one would not write "if the last operation
produced an overflow" in most modern code, although that is generally
how a processor implements if statements.

Similarly, early returns can sometimes hurt code readability... and
sometimes it can help readability.

So rather than blathering on a guideline, understand why someone made
that guideline and then judge whether or not it applies.

In terms of early returns, I personally feel that early return on error
is more readable whereas early return on success is more nuanced:
sometimes it's more difficult to understand, other times it's easier. YMMV.
 
A

Arved Sandstrom

Joshua said:
There are no hard-and-fast rules: in general, every guideline will have
cases where one can and should ignore the proposition at hand.

Take for example the infamous goto statement. If you read Dijkstra's
original letter
(<http://www.cs.utexas.edu/users/EWD/ewd02xx/EWD215.PDF>), you'll notice
that he disliked goto not because it wasn't useful, but because it was
too primitive, much like how one would not write "if the last operation
produced an overflow" in most modern code, although that is generally
how a processor implements if statements.

Similarly, early returns can sometimes hurt code readability... and
sometimes it can help readability.

So rather than blathering on a guideline, understand why someone made
that guideline and then judge whether or not it applies.

Absolutely. That's why the best Effective This or Exceptional That books
don't just spew out a list of guidelines, they include a mass of
discussion with each guideline.
In terms of early returns, I personally feel that early return on error
is more readable whereas early return on success is more nuanced:
sometimes it's more difficult to understand, other times it's easier. YMMV.

Nicely summarized - this is exactly the way I see it. With respect to
the last paragraph, early return on error is generally held to be a
sensible thing to do; the classic example is a main() method in
C/C++/Java/C#, where if your CL arguments don't pass some simple tests
you may as well punt right away.

With respect to early return on success, I agree, it's nuanced.
Readability is the main factor for me. There is one case where I
probably do have a rule - this pattern:

<returnType> someMethod(...) {

<someType> retVal = <defaultValue>;
// some whack of code
...

if (someConditions) {
// another whack of code, including possibly more
// conditionals
...
retVal = <somethingOtherThanDefault>;
}

// more code
...

return retVal;
}

That is, the bulk of the code in "someMethod" will result in the return
value being the default, and there's only the odd situation here and
there that may determine otherwise. In this case I find it helps
readability not to have else blocks that do nothing but set the return
value to what would be a usual default.

AHS
 
A

Arved Sandstrom

Arne said:
There is a pretty good chance that those gentlemen are correct.

That's normally my operating assumption. :) In fact some of the recent
threads here got me back to re-reading Code Complete by McConnell.

[ SNIP ]

AHS
 
T

Tony Proctor

Joshua Cranmer said:
There are no hard-and-fast rules: in general, every guideline will have
cases where one can and should ignore the proposition at hand.

Take for example the infamous goto statement. If you read Dijkstra's
original letter (<http://www.cs.utexas.edu/users/EWD/ewd02xx/EWD215.PDF>),
you'll notice that he disliked goto not because it wasn't useful, but
because it was too primitive, much like how one would not write "if the
last operation produced an overflow" in most modern code, although that is
generally how a processor implements if statements.

Similarly, early returns can sometimes hurt code readability... and
sometimes it can help readability.

So rather than blathering on a guideline, understand why someone made that
guideline and then judge whether or not it applies.

In terms of early returns, I personally feel that early return on error is
more readable whereas early return on success is more nuanced: sometimes
it's more difficult to understand, other times it's easier. YMMV.

I would have to agree with you there Joshua

You know, this subject (GoTos, early exits, program flow, exception
handling, blah, blah) occurs in virtually every language group, and no final
resolution is ever reached because the questions are not the right ones, and
the responses too parochial.

Modern computers all have 'GoTo instructions' (aka branches), but does this
make their instruction sets intrinsically bad? No, it depends entirely on
their usage of course.

To a great extent, it comes down to readability as Joshua has said. Some
people can right awful code without the aid of GoTos. In fact 'flags' are
probably more dangerous than GoTo. I've seen so many instances of code where
flags have been introduced solely to keep to some structured paradigm, but
the flags have no real-world significance and the result is a different type
of 'spaghetti code'.

Re: 'early exits', I'm pragmatic about these, as with many things. Most
cases are borderline and come down to personal style and readability (see
above). However, I have also come across examples where they're by far the
most readable and practical solution because there are so many 'exceptional
cases' to remove from the real logic to follow below. Enforcing some
structured programming criterion would simply send the indentation flying
off the end of the page, or introduce flags that have no real-world
significance.

In summary, if the code looks aesthetically pleasing then it's got a high
chance of being good code and will probably look good to others too.

.... interestingly, this same aesthetic principle applies to some extent in
theoretical physics: if the equation is simple and elegant and it's probably
the right one :)

Tony Proctor
 
T

Tom Anderson

Frank Rubin (March 1987). ""GOTO Considered Harmful" Considered Harmful"
<http://www.ecn.purdue.edu/ParaMount/papers/rubin87goto.pdf>

"[Banning GOTOs] is like butchers banning knives because workers
sometimes cut themselves."

Aha! By amazing coincidence, i was reading Dijkstra's response to this
recently, but for a completely unrelated reason, and i had no idea what
this Rubin letter was:

http://www.cs.utexas.edu/users/EWD/ewd10xx/EWD1009.PDF
http://www.cs.utexas.edu/users/EWD/transcriptions/EWD10xx/EWD1009.html

I'm not really sure what his point is, since his little program is pretty
much the same as Rubin's goto-less strawman, but in a notation which makes
it look more elegant.

What struck me is that neither Rubin nor Dijkstra did what i would have
done (note - in the below code, i eschew java-style things like foreach
loops, passing pointers, and exceptions, and restrict myself to the
passing-integers-around style of the above examples), which is either a
labelled continue:

public void printFirstZeroRow(int[][] x) {
rowloop:
for (int j = 0; j < x.length; ++j) {
for (int i = 0; i < x[j].length; ++i) {
if (x[j] != 0) continue rowloop;
}
System.out.println(j);
return;
}
}

Or decomposition into functions which use early returns:

public void printFirstZeroRow(int[][] x) {
int firstZeroRow = findFirstZeroRow(x);
if (firstZeroRow != -1) System.out.println(firstZeroRow);
}

public int findFirstZeroRow(int[][] x) {
for (int j = 0; j < x.length; ++j) {
if (isZeroRow(x, j)) return j;
}
return -1;
}

public boolean isZeroRow(int[][] x, int j) {
for (int i = 0; i < x[j].length; ++i) {
if (x[j] != 0) return false;
}
return true;
}

These are goto-free and involve no unnecessary variables. The former is a
little bit icky by virtue of the labelled continue, but i think the latter
is absolutely fine.

But maybe this is kind of the point: goto has been replaced by what are
essentially restricted versions of it - labelled breaks and continues are
very goto-like, but crucially restricted so that they're much simpler to
understand, and even early returns have something slightly goto-esque
about them, although of course they have almost none of the scope for
abuse. Maybe that's why the arbiters of style have often frowned on
multiple returns?

tom
 

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,811
Messages
2,569,693
Members
45,478
Latest member
dontilydondon

Latest Threads

Top