Why braces around try/catch?

  • Thread starter Henrik S. Hansen
  • Start date
J

Jos A. Horsmeier

EJP said:
Sorry, no. After 's1;' the only legal continuation for the program is a
'catch', so a compiler would give a 'try without catch' error at the
first 'while', and initiate recovery. Recovery would need to skip the
'catch'. The compiler would then treat the second 'while' as beginning a
'while' statement with an empty controlled-statement.

I beg to differ; catch clauses are optional as in --

try {
// some statements making
// up the statement block
}
// no catch

Leaving out the mandatory pairs of curly braces in the syntax of a try
block and a do-loop ambiguates the whole shebang as I showed in my
previous example.

kind regards,

Jos
 
B

Bent C Dalager

I beg to differ; catch clauses are optional as in --

try {
// some statements making
// up the statement block
}
// no catch

I'm not sure what you mean. If I compile the above I will get a
compile error along the lines of
'try' without 'catch' or 'finally'

Cheers
Bent D
 
J

Jos A. Horsmeier

Bent C Dalager said:
I'm not sure what you mean. If I compile the above I will get a
compile error along the lines of
'try' without 'catch' or 'finally'

How peculiar; according to the JLS (http://java.sun.com/docs/books/jls/second_edition/html/statements.doc.html#79311\
a try statement doesn't need catch clauses, i.e. catch clauses are optional
(as indicated in the grammar) and nowhere in the JLS can be found that a try block
needs at least one catch block as some sort of additional restriction ...
I'll check it out.

kind regards,

Jos
 
C

Chris Smith

Bent said:
I find that the braces emphasize the control flow in the program,
which can only be a good thing.

I also find that braces emphasize control flow in the program, and I
also think that's a good thing. In addition to that, though, they also
make a bigger production of what is often a simple concept. That's a
bad thing, because it make idiomatic reading of code difficult, and
intrudes on the omprehension process. I find that the trade-off between
these two factors in simple control flow statements often favors the use
of if statements without braces (though rarely so for more complex
statements like loops or switch).
Seeing as I use indentation for
non-flow purposes (specifically, continuing long lines), always having
the braces when an indentation signifies a new program block (even if
only a one-liner) makes it much _easier_ to read the code, IMO.

That's a non-issue. I don't advocate omitting braces when only
indentation would indicate the statement relationship. I advocate
omitting braces for very simple predicates to form one-line statements
such as:

if (!canContinue) return;
if (input < -1) return -1;
if (!flag[j]) continue;
if (s == null) s = DEFAULT_VALUE;

et cetera
I am altogether very liberal in using vertical space to emphasize code
structure - vertical space is basically free anyway.

It isn't a matter of cost; it's a matter of vertical space
psychologically conveying something about the code, and not wanting to
mislead the reader wy using copious vertical space to express a trivial
concept.

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
C

Chris Smith

Thomas said:
This argument is common, and IMHO falls appart only for the following
reason: You must take into account how /often/ something is happening.

I don't understand, perhaps. My perspective is that if a programmer is
frequently making errors relating to basic construction of code, even if
I can prevent those errors, I'd assume that programmer is making even
more errors, which are harder to find, in interactions with other parts
of the application. Even if I could avoid any kind of error relating
purely to language construction, I wouldn't trust the code I get out of
a programmer that didn't know the language anyway.
For example, I like the fact that you cannot perform array arithmetic in
java. Why? Not because totally seasoned programmers get into trouble,
though they do. But, because so /many/ programmers produce code with it
that shoots /me/ in the foot and further, delays the shipment of the
product.

Different issue, though. The errors you mention in this latter
paragraph are errors in logic, not errors in understanding how the
compiler will parse a block of code. The two are entirely different
matters, as I see it.

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
B

Bent C Dalager

That's a non-issue. I don't advocate omitting braces when only
indentation would indicate the statement relationship. I advocate
omitting braces for very simple predicates to form one-line statements
such as:

if (!canContinue) return;
if (input < -1) return -1;
if (!flag[j]) continue;
if (s == null) s = DEFAULT_VALUE;


I don't have a problem with omitting braces for these. It's when one
might have written

if (something)
callSomeMethod();

that I would add the braces. Of course, in this specific case, I might
just as well choose to put it all on one single line, depending on how
important I think it is.
et cetera


It isn't a matter of cost; it's a matter of vertical space
psychologically conveying something about the code, and not wanting to
mislead the reader wy using copious vertical space to express a trivial
concept.

It _was_ a matter of cost back in the days when all you could count on
was 25 lines, and you'd only get 50 if you were lucky. At that time, I
would never put start braces on their own lines because vertical space
was too expensive.

Which is why I emphasize that the reason I use vertical space to bring
out the code structure today is, for me, a question of cost.

Of course, as you say, once I have determined that the space cost is
no longer relevant, it boils down to a question of how, exactly, to
format the code in order to make it intuitive for the casual reader.

Cheers
Bent D
 
D

Dale King

Chris Smith said:
Well, no... now I understand that you have a correct understanding of
the current language, but am still lost as to how your statements apply
to the conversation.


Once again, whether the compiler generates different code with or
without braces is not the issue. Human beings do care about braces, and
generally consider statements with braces a bit more tedious than
statements without them, if nothing else because they take up more space
on the screen, and so necessarily occupy a larger portion of the task of
reading a screenful of text.

This human being finds the complete opposite. I find braces a great aid in
reading the code. If a method is taking up an entire screenful of text then
it will generally be hard to read because it is more than the brain can hold
at one time. The addition of braces do not really make it harder to read.
The solution is to refactor and break it up more so it is not a screenful of
text rather than taking away the braces that give you the visual clues to
break it down into smaller units.
Because try statements require braces,
they have a larger conceptual footprint to the programmer.

Not as I see it. The braces serve to provide a demarcarcation between those
things that are within and those without. That splits things into making two
things with smaller conceptual footprints than the whole.
As a result,
programmers make choices that reduce the number of try blocks by
combining several error-recovery tasks into a single block.

That is a separate issue though than what you described above.
That can
omplicate things, where a simple no-brace try/catch statement could have
avoided the need.

At the expense of making it harder to read.
 
D

Dale King

Chris Smith said:
I also find that braces emphasize control flow in the program, and I
also think that's a good thing. In addition to that, though, they also
make a bigger production of what is often a simple concept. That's a
bad thing, because it make idiomatic reading of code difficult, and
intrudes on the omprehension process.

Once again I conclude the exact opposite. Having a single idiom rather than
multiple idioms for the same construct (e.g. if) makes an idiomatic reading
of code difficult. I can get a quick concept of the overal structure of a
piece of code without having to actually read the text of the code.

I like Steve McConnell's idea in Code Complete of layout where he uses
abstract pieces of code without text. It is as though you looked at the code
without focussing and you see that there are letters there but cannot see
what the letters are. The process of understanding the code is to go from a
fuzzy image to a sharper and sharper image.

Imagine it as if we ran the code through a scrambler that changed all the
letters to random printable characters. So a piece of code may look like:

sdfsdfsf = ( sdfsfo + safdasf ) * ppokwqe;
sd( sdfpookpe > sdofisdoijwe )
{
ersr.gfdpok( dfdgpod, dfpogdfpok );
}

To take it even further actually let your eyes defocus a little or actually
back away from your monitor a bit so that you don't quite

With this "fuzzy" look at the code we can quickly see that there is some
control structure there. We next need to know what kind of control
structure. We need to find the beginning of the control structure. This is
where having the brace on its own line. It is much easier to find the
opening brace than trying to find the change indent (I also would have put a
blank line before the if to make it easier to find). We then easily see that
it is an if. What I described in so lengthy of a process really takes a
fraction of a second and we have discovered the general structure of the
code before looking at any specifics.

On a side note I did not scramble the puncuation characters. This is only
because I used spaces around them to set them off. If we did not have the
spaces they would blend in with the text characters and would not be
discernable at this level of fuzziness. That is one reason why I advocate
this practice.

Contrast that with the version without braces

sdfsdfsf = ( sdfsfo + safdasf ) * ppokwqe;
sd( sdfpookpe > sdofisdoijwe )
gfdpok( dfdgpod, dfpogdfpok );

If you take a fuzzy look at this you can't tell for certain what the
structure is. It is just a blob of code. There is an indent so that may be
important or it may just be that the previous line was too long and was
continued to the next line. At this level of fuzziness it is hard to tell.
We have to focus in more to find out. It will certainly take longer to
discover.

It is really no different than how I have put blank lines between the
paragraphs of this message. There is no actual requirment that I do this.
But it is certainly easier to read. (If you want to try an experiment go get
some novel at Project Gutenberg and remove the blank lines between the
paragraphs and see how long you can endure reading it). If you were to make
a fuzzy view of this message by doing a rot-13 of it, the structure would
still standout even though you understood none of the words.

But perhaps I am not the only one that reads code this way.
I find that the trade-off between
these two factors in simple control flow statements often favors the use
of if statements without braces (though rarely so for more complex
statements like loops or switch).

And I find that it never favors any control structure without braces. There
are some constructs that sort of compromise this (such as break, continue,
throw, and return) but I don't want to get into another discussion of goto,
etc.
Seeing as I use indentation for
non-flow purposes (specifically, continuing long lines), always having
the braces when an indentation signifies a new program block (even if
only a one-liner) makes it much _easier_ to read the code, IMO.

That's a non-issue. I don't advocate omitting braces when only
indentation would indicate the statement relationship. I advocate
omitting braces for very simple predicates to form one-line statements
such as:

if (!canContinue) return;
if (input < -1) return -1;
if (!flag[j]) continue;
if (s == null) s = DEFAULT_VALUE;


Eeek! The last one might be excusable as it is a simple assignment. But
hiding statements like that which are control flow statements is an
abomination. I always use braces and the else to show that there is a change
in control flow.
It isn't a matter of cost; it's a matter of vertical space
psychologically conveying something about the code, and not wanting to
mislead the reader

How can making something clearer be misleaading the reader?
wy using copious vertical space to express a trivial
concept.

The longer I program, the more I learn that there are fewer and fewer
trivial concepts.
 
J

Jos A. Horsmeier

Dale King said:
Jos A. Horsmeier said:
I beg to differ; catch clauses are optional as in --

try {
// some statements making
// up the statement block
}
// no catch
I'm not sure what you mean. If I compile the above I will get a
compile error along the lines of
'try' without 'catch' or 'finally'

How peculiar; according to the JLS a try statement doesn't need catch
clauses, [ ... ]
It is spelled out completely in section 14.19 by the grammar rules that show
that catches are only optional if there is a finally:

TryStatement:
try Block Catches
try Block Catches(opt) Finally

The opt was subscript in the grammar rules to show that it was optional.

Ah! Thanks for correcting me; my imagination had changed the second line
into a 'try Block Catches(opt)' also ... silly me.

But still, leaving out the curly brackets (as has been suggested here
before) is not a wise thing to do, e.g.

try <statement> try <statement>
try <statement> try <statement>
catch(...) <statement> catch(...) <statement>
catch (...) <statement> catch(...) <statement>
finally <statement> finally <statement>

This leaves us with a 'dangling catch clause' ...

kind regards,

Jos
 
J

Jacob

Dario said:
If you have not braces how do you interpret the following code:

try
s1();
catch(Exception e1)
try
s2();
catch(Exception e2)
s3();
catch(Exception e12)
s12();

as the following?

try {
s1();
}
catch(Exception e1) {
try {
s2();
}
catch(Exception e2) {
s3();
}
}
catch(Exception e12) {
s12();
}

or as the following?

try {
s1();
}
catch(Exception e1) {
try {
s2();
}
catch(Exception e2) {
s3();
}
catch(Exception e12) {
s12();
}
}


You decide by convention, equivalent to this:

if (clause1)
statement1;
else
if (clause2)
statement2;
else
statement3;

According to the convention the last else
will connect to the closest if. If the same
convention was used with try, your problem
would be solved.

See <http://makeashorterlink.com/?D11A62785>
and finally stop this thread!

You decide this?
 
D

Dale King

I think we need to clear up the definition of "idiom". You seem to mean
"syntactical construction", where I'm going a bit higher level, and
referring to a programmer's use of those language constructs in a
specific way. For example, the standard for loop for integer indexing:

And I was using it as a way of expressing some desired action with a
syntactical construct. For example, to set a variable to one of 2
different values one idiom would be to use an if-else. Another idiom
would be to use the conditional operator.

In this case, one idiom for doing a conditional is to spell it out with
braces and another is to use a single line. If I only use the single
idiom of spelling out the if's it is always easier to pick out and
identify the conditionals. In other words it makes an idiomatic reading
easier because I only use one idiom.
You see, there are two elements that go into making a good idiom: it
must be easily recognizable,

Which is where I fault the single line if. It is not easy to recognize.
and it must be easy to dismiss the
idiomatic construction and get to the heart of the matter.

I find that much easier with the verbose if.
This is, in
fact, the whole reason that 'for' is better for idiomatic array looping
than 'while'. There's really not a whole lot of extra typing involved
in writing:

int i = 0;
while (i < array.length)
{
...

i++;
}

but that's not so good for idiomatic reading of the code because the
idiom is spread out more, and thus more difficult to dismiss after it's
been recognized and categorized.

And I say its bad because it is not as easily recognized what is
happening as it is with the for. Therefore one should only use a single
idiom for this.
That seems to me a perfect parallel,
in fact, as for was specifically introduced as a redundant syntax in the
language because it's better for concise expression of idiomatic
elements of the language.

Terseness is not high on my prioirty list. The advantage of the for is
that, in its usual incarnation, it puts all the information about the
"loop control" into one place separated from the the processing done on
each iteration. The while loop intermingles those and separates the
declaration of the variable entirely.

So in my opinion it is not the terseness, but the logical grouping that
is important in the for statement.
With single line conditionals, the idiomatic elements are generally
defined more by the context. For example, I frequently find myself
writing code like the following (which it looks like you'll detest with
a passion):

You've got that right. For one thing you have many control flow paths
there represented with no structure or visible clues that it is
occurring.
for (int i = 0; i < array.length; i++)
{
if (array == null) continue;
if (!array.isVisible()) continue;
if (!array.needsUpdate()) continue;

// update the member:
...
}

I firmly believe that the three short lines written at the top of the
loop body, each clearly giving a condition on which we skip this item,
are more readable that the expanded form:


I would at least for a start change that slightly to show the control
paths

for (int i = 0; i < array.length; i++)
{
if (array == null)
{
continue;
}
else if (!array.isVisible())
{
continue;
}
else if (!array.needsUpdate())
{
continue;
}
else
{
// update the member:
...
}
}

But that is not how I would write it. Since you can make it more
straightforward by not using the continue and reversing the logic, but
I'll do that further down.
That's just tedious... not to write, as it really takes no longer to
write this than the previous form, but to process mentally when I see
it.

(Incidentally, you may suggest:

if ((array == null)
|| !array.isVisible()
|| !array.needsUpdate())
{
continue;
}

or even:

if ((array != null)
&& array.isVisible()
&& array.needsUpdate())
{
...
}


No, I really don't like complex if conditionals. I find myself more and
more using the refactoring of Introduce Explaining Variable:

http://www.refactoring.com/catalog/introduceExplainingVariable.html

So for many complex conditionals I introduce more meaningful variables.
It is probably overkill in this case however. Because there is a
necessary ordering to the conditions, I would make that more explicit in
the code. Here is probably how I might do it eliminating the continue
statements:

for( int i = 0; i < array.length; i++ )
{
Foo element = array[ i ];

if( element != null )
{
if( element.isVisible() && element.needsUpdate() )
{
// update the member:
...
}
}
}

I would much rather see this than your version. This version adds 2 extra
lines, which are for the variable I introduced to provide a name to the
element instead of propogating the array indexing throughout.

I fail to see how anyone would fail to find that more readable than
yours. It greatly simplifies the control flow structure. While I am not
an anti-goto zealot I see no reason to introduce jumps when there is
definitely no need.

Another way to go would be to encapsulate the conditionals into a single
method call and we could then code it as:

for( int i = 0; i < array.length; i++ )
{
if( elementShouldBeUpdated( array[ i ] ) )
{
// update the member:
...
}
}
and I agree that's better than the second form, but it suddenly requires
parsing a long complex conditional, involving mentally matching multiple
levels of nested parentheses. I wonder if I'm alone in thinking that's
one of the most painful tasks possible in reading code. I far prefer a
series of parallel, simple statements to a long conditional expression.)

I certainly agree. I rarely ever use a conditional that takes more than
one line. As I said, I prefer to introduce explaining variables. In this
case the calls were self-documenting and not overly long.
That's a long form of what I meant when I said that shorter forms lend
themselves to writing code for easier idiomatic reading.

Not proven by this example. I think my version is much easier idiomatic
reading.
I like Steve McConnell's idea in Code Complete of layout where he uses
abstract pieces of code without text.

I 100% agree with you that this is important, though I didn't recall it
being in Steve McConnell's books. I thought about this to some depth
before I wrote the article you're replying to. I almost mentioned it
there, but I ended up not addressing it... mostly because I didn't trust
myself to properly explain the idea before going on to explain that I
don't think it applies.

Now here's why I don't think it applies: it all eventually comes down to
something I've talked about in this newsgroup before, generally without
making much of an impression: a gap where abstraction and encapsulation
[for lack of a better word, but not the practical OO kind of
encapsulation] don't quite line up, and the developer wants
encapsulation without the abstraction. Some people just get up on a
soapbox and proclaim that these situations don't exist; I think those
people are fooling themselves.

This is going to get somewhat difficult to explain, so please bear with
me. First some definitions: By encapsulation, I don't mean hiding from
a language perspective. I just mean a general quality of bundling
things together and dealing with them as a group. It's actually closely
related to my discussion of idiomatic reading above: something that's
encapsulated in this sense is easy to label and put out of mind.

Abstraction is something more than that; it requires encapsulation, but
it isn't implied by encapsulation. Abstraction is the quality by which
higher meaning an be assigned to the whole than to the sum of the parts.
It's basically indicated by the ability to give the whole a name that's
more expressive than the code that implements it.

Now abstraction indicates a need to refactor something into a named
method or even class. Mere encapsulation would be very awkward to
refactor, and requires just shoving it out of consciousness as much as
possible so that the main point of a piece of code can be understood,
because the code is still the clearest representation of what's
happening. Refactoring into another method would require that you try
to pick an identifier which does as good a job as possible of expressing
what's in the code, but can never be as good as the code itself. (If you
can pick an identifier that's better than the code, then you should go
for it, and the result will be abstraction rather than just
encapsulation, and you'll have done well to refactor it.)

As an interjection here, this is not all academic. I worked for most of
this past year with a developer who didn't get this, and tried her
hardest to generate identifier names for extracted methods that never
quite lived up to the idea of abstractions. I still have to
occasionally change part of that code and encounter methods named
insanely long things, involving lots of 'and' and 'if' and 'while' in
the identifier, than still never quite accomplish explaining what the
code does well enough that I avoid the need to go read the method
anyway.

Now, here's my contention: I don't think it's any worse to "hide" an if
statement to reduce the impact in a piece of code than to "hide" an if
statement in a call to a refactored method. If no loops or conditions
were ever hidden, then all control flow keywords would occur in main!
Obviously, you'd be in favor of hiding them in extracted methods and
classes, but for some reason de-emphasizing them in included code
doesn't sit right with you.

I don't agree with your intentions here. The purpose is not to hide. I
disagree that the intent is to put things out of mind. I see the intent
more to separate things into smaller more digestible units. With an if we
are separating into the unit of what happens when the condition is true,
what happens when it is not true, and what the condition is. This is
separated from the code that surrounds it.

We do this because of the limited size of our skulls. We can only keep
track of a few things at once. I guess this would fall under your meaning
of encapsulation. We want to encapsulate the things we have to keep track
of while reading the code into manageable units. But it seems to me that
you then try to bury or hide those units. They are not out of sight or
mind because they aren't encapsulated they blur into their surroundings.
When I am looking at the update code it is not clear that there are
conditions that have to be fulfilled to get there. Within the update code
you might wonder could the element be null or invisible? You would only
know that by reading the top of the body and parsing it out. In my
version those questions are answered by the context. The update code very
clearly is in the context of not-null, visible and in need of update.
So in the end, you have to admit that hiding control flow is necessary,
and you just aren't comfortable with my in-between way of doing it.

No, I do not admit that hiding is necessary just for the sake of hiding.
I see this as a matter of trying to retain the ability to format code so
as to convey a message about its meaning.

You want to convey the meaning by hiding it??
if (!canContinue) return;
if (input < -1) return -1;
if (!flag[j]) continue;
if (s == null) s = DEFAULT_VALUE;


Eeek! The last one might be excusable as it is a simple assignment. But
hiding statements like that which are control flow statements is an
abomination. I always use braces and the else to show that there is a change
in control flow.


Is this beause you think the conditional somehow makes things worse, or
because you generally dislike statements like break, return, and
continue. The if doesn't hide a return or continue any more than if it
appeared on a line by itself, by your rot13-on-the-code standard.


No, I am not a purist that is against them. They (and you can include
throwing an exception as well) cause an *implicit* non-linear jump. If
one can, you should try to make that explict as much as possible, such as
my first example where I used else to make the divergence in control flow
explicit. The usual example is checking method parameters. Instead of

if( parameterBad ) throw ...
// normal flow

I would do it:

if( parameterBad )
{
throw ...
}
else
{
// normal flow
}

Of course there are cases where this really can't be made explicit in a
two-dimensional space, such as the classic example of the search loop.
In essence, I think the issues are orthogonal. If you didn't mind those
keywords, there's not additional reason to dislike them when used with
an if statement in a single-line form. I could be wrong, though.

I don't think they are orthogonal, because they both affect the control
flow. One is implicit and one explicit (as in made visible structurally).
The explicit one can be used to make the implicit one more visible.
In the same way I can mislead a reader about my intent and what they can
expect by spending 50 pages explaining the Newtonian physics of bullets
at the beginning of an action movie script. It just doesn't deserve
that much attention. Screen space IS attention.

I don't think that applies here. It gets back to your encapsulation. If I
encapsulate that so it can be separated. To continue the bad analogy here
you can include the physics lesson in an appendix.
And I think the main lesson from software development is that you can't
think about everything all of the time. Something always has to be
assumed, which means it's trivial in the context of the current issue.

I addressed this above.
 
D

Dale King

Thomas G. Marshall said:
Consistency, as you put it, can obfuscate if it means that you must add
control structures where non are needed.


Yep. There is a very fundamental concept here. There has always been a
notion through the years that source code need not be latched to ascii
characters droning on and on. This notion does not necessarily require that
the code is stored in database form. It just means that the presentation
ability is gussed up.

There have been many times I've wanted to edit my code just like a word
document. I've wanted to make something highlight. I've wanted to actually
(!) drop in a small image in a gui app to explain what a particular
algorithm is actually doing. I've thought that it would be neat to drop in
a UML (hierarchy only) diagram not in ascii-art. etc.

You can do that right now. Not to be seen in the text view of the source
code, but you can certainly do it in the JavaDocs. It would be really cool
if an IDE actually parsed the javadocs and provided you a real view of the
HTML within the editor itself.
 

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,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top