why does catching errors that aren't thrown give syntax errors?

L

Lew

Because the JLS says so.

blue said:
It was intended as constructive criticism. As, I believe, are some of the
posts you make that I characterized as spelling flames and similarly, but
which maybe could be improved upon, for example by never neglecting the
core point of the preceding post and sometimes by recognizing a lost cause
(such as attempts to educate spammers and trolls).

Perhaps you don't agree.

Carry on, then.

It seems that in your eagerness to criticize me personally (and, I
notice, not the others who gave the same answer with somewhat more
detail) that you completely ignored the point I made. At least you
use the term "begging the question" correctly. However, I was not
begging the question. I was giving the only actual, valid answer to
the question.

A number of people have offered reasons why the rule *could* have been
made. Others offered reasons why the rule *shouldn't* have been
made. However, without recourse to the reasoning behing the rule, and
I don't see Java's authors responding in this thread yet, no one has
answered the OP's question as to why the rule *was* made.

For some reason, Java engenders more armchair language design than any
other computer language I've used. No one seems to ask, "Why does
Perl have such opaque syntax?" Instead, they argue religiously that
it's far superior by dint of that very opacity. Java is the only
language that receives criticism from its adherents rather than blind
devotion. This is a good thing, and one of its strengths. But
ultimately, the reason why one has to do what one has to do in any
computer language is that that's how the language is defined. "Why is
it that way?" is not a useful question, and always the trivial answer
is the correct one, "Because that's the definition of the language".

Now, were one to ask, "Should this change?" that would be useful.

So next time, blue indigo, do not rush to judgment but consider why I
gave the answer I did, and incorporate the possibility that the answer
was serious, thoughtful and relevant.
 
B

blue indigo

It seems that in your eagerness to criticize me personally (and, I
notice, not the others who gave the same answer with somewhat more
detail) that you completely ignored the point I made.

Ah. I see you noticed that it was the lack of detail that made the
difference.

It should be obvious, and apparently it was obvious to several other
people, that the OP wanted to know the rationale behind forbidding the
unreachable catch. "Because the JLS says so" is not then a satisfying
explanation.

It's reminiscent of the kind of nonsense you tend to get when someone
either doesn't want to admit that they don't know the answer to something,
or is just being arbitrary and authoritarian.

"Why?"
"Because the JLS says so."
"But why does the JLS say so?"
"Because someone at Sun thought it was a good idea."
"But WHY???"

If you've ever had, or taught, or been around a small child, you'll know
that this sort of answer never satisfies.

To see one on usenet is somewhat mystifying though. Most of the usual
reasons for such non-answers don't apply. You didn't decide this, so
you're not just putting your foot down and saying "Because I said so ...
JUST BECAUSE!"; maybe you don't know and would rather not say "I don't
know", but you can easily remain silent on usenet and your silence will
probably go unnoticed (whereas your non-answer definitely did not).
I was giving the only actual, valid answer to the question.

The OP wants to know the reason for something. Because some document says
so is not a real reason; it's just an expression of a decision that
somebody made, the reasoning behind which remains unexplained by your
"answer".

Some of the explanation of the reasoning, in this case, is apparently
described in the text of the JLS, but your post made no reference to this
fact, so I discount it here.
Java is the only language that receives criticism from its adherents
rather than blind devotion.

I find this surprising, if true. My expectation would be that any
programming language in widespread practical use is going to be the
subject of debates, criticism, and discussion among its practitioners.
Abnd that there will be some subset that treat it as an object of
religious veneration and are purists and change-resisters, too.

Certainly I've seen web sites asserting that Java is a religion to some
people. It's unsurprising that perl is to others. Probably the only one
that isn't is COBOL. :)
"Why is it that way?" is not a useful question

I disagree.

It may not be useful in day-to-day coding, but it is certainly useful when
you take the longer view in which there is a give-and-take between the
user community and the developers. Java, in particular, has a
participatory community process and its bug tracker accepts feature
requests and has an explicit "this is a feature request, not a bug report"
option in it, so in the longer view in which one seeks to influence the
evolution of the language one certainly has use for information about the
reasoning behind various design choices.

On the one hand, knowledge of the reasoning behind a choice might lead one
to decide that one agrees with that reasoning. That might forestall
opposition to something that seems quirky but turns out to have good
reasons behind it. Absent such an explanation, the community process might
make a short-sighted mistake by overturning a rule that turned out to be
more beneficial than it seemed at first blush.

On the other, perhaps the choice was truly arbitrary, or the reasoning
behind it contains an error, in which case it may be wise to revisit it
down the road. It may not -- some arbitrary choices are pointless to
change. For example, which side of the road you drive on in a country. The
choices are basically symmetrical at the outset, so the decision might as
well be made by a flip of the coin, or to be consistent with neighboring
countries, or whatever. Afterward though there's a huge cost and no
benefit to switching, whichever way it was originally set. The choice of
side is an assumption buried in the infrastructure, everywhere there's a
turn lane or a signal light, and lots of other places besides. Businesses
spring up downstream of highway offramps -- gas stations, fast food joints
-- that would suddenly be upstream of an onramp instead after such a
change. Similarly there may be decisions in Java's design that are
similarly arbitrary but not worth revisiting.

And there may be some that are worth revisiting.

Knowing which are which and having an informed debate could be useful for
the future evolution of the language. Stifling such knowledge and
preventing informed debate, out of a misguided belief that it's useless or
that there can be no such knowledge, certainly cannot be useful.
and always the trivial answer is the correct one, "Because
that's the definition of the language".

Trivial-and-correct answers are frequently also nearly useless.
Now, were one to ask, "Should this change?" that would be useful.

I'm glad you realize that. But part of answering "should this change?"
tends to involve answering "why is it this way to begin with?"; if one
does not learn from history one is doomed to repeat it.
So next time, blue indigo, do not rush to judgment

I don't think I did. I have well-thought-out reasons for nearly everything
I say, as I hope I have now demonstrated.
but consider why I gave the answer I did, and incorporate the
possibility that the answer was serious, thoughtful and relevant.

Consider the context. Here we have the OP asking why something is the way
it is in Java, several cogent and detailed responses detailing a
rationale, and then one post from you that amounts to "just because". You
can understand why that does not look particularly serious, thoughtful, or
relevant. Indeed, since others had mentioned that the JLS specified the
behavior in question, it looks more redundant than relevant or much of
anything else.
 
B

blue indigo

The "#if 0" method was the canonical way to suppress a
bunch of code from compilation in early C days (a '/* */' would not do
the trick in full generality, since such comments do not nest).

That must rank up there on the "all-time top 100 boneheaded decisions"
list. "Such comments do not nest," that is. They even have a distinct left
and right delimiter, so it would have been trivial to make them nest
appropriately, and doing so would have made it very easy to comment out
large blocks of code containing pre-existing comments. Yet they did not,
probably out of sheer laziness.

// comments were introduced to C++ (and later backported to C) partly to
address this, only to run into their own problems:

- You can now use /* */ to easily comment out a lot of code containing
only // comments.
- You can now use // to comment out a lot of code containing arbitrary types
of comments.
- But it takes a lot more typing to insert "// " at the start of each of
1000 lines than to insert "/*<RET>" at the top and "*/<RET>" at the bottom.

Better would have been to require /* */ comments to nest properly in C++,
and eventually backport THAT to C. It wouldn't have even broken anything,
since */ is not legal outside of a comment, so changing the parsing rules
for comments in the appropriate manner wouldn't have caused valid code to
suddenly become comments in pre-existing compilable code.

Java would have benefited too, since it inherited the C++ system of
commenting syntax.
 
B

blue indigo

According to blue indigo said:
On Mon, 5643 Sep 1993 22:31:37 +0000, Thomas Pornin wrote:
[snip]
Regardless of what the compiler thinks about exceptions, the JVM will
happily accept all of these because transgressions of the "checked
exceptions" rules do not impact the safety of the sandbox model that the
JVM implements.

And transgressions of the "dead code" rules do? How?

Yes, although a bit indirectly. [snip lots of details]

It sounds like it does not actually create a risk of crashes or hacking.
Sure, the dead code can't be verified not to do something bad. Except that
since it's never executed, it will never get the chance.

It also complicates JIT design -- slightly. The obvious thing is for dead
code to not be compiled at all, as an optimization, and it sounds like
this is already the case with Sun's Hotspot JIT.

Frankly, I don't see what the big deal is here.

It seems a bit like worrying about letting elm trees within city limits
because they might potentially harbor Dutch elm disease, which would be
horrible if it somehow afflicted people, despite the fact that it's not
actually transmissible to humans. Or something like that.
 
B

Bent C Dalager

Better would have been to require /* */ comments to nest properly in C++,
and eventually backport THAT to C. It wouldn't have even broken anything,
since */ is not legal outside of a comment, so changing the parsing rules
for comments in the appropriate manner wouldn't have caused valid code to
suddenly become comments in pre-existing compilable code.

/*/*char* txt1 = "*/char* txt2="*/";

Cheers,
Bent D
 
B

blue indigo

/*/*char* txt1 = "*/char* txt2="*/";

Yes, of course it would have to take quotation marks into account as
well as /* and */.

I thought that went without saying, sorry mate.

The corner case you point out ought to be rare in practise. How common is
it for string literals containing C source to occur in C source? Outside
of quines and IOCCC submissions, anyway.
 
B

Bent C Dalager

Yes, of course it would have to take quotation marks into account as
well as /* and */.

This then becomes a considerably more complex change than what you
outline above and one that is sure to meet with, shall we say,
spirited debate in the larger C community.
The corner case you point out ought to be rare in practise. How common is
it for string literals containing C source to occur in C source? Outside
of quines and IOCCC submissions, anyway.

That is really of no interest whatsoever. All that needs to be
demonstrated is that there can exist code that will break after the
change and such a demonstration, however eccentric, is sufficient to
disprove the claim that the change can safely be introduced with no
further ado. As a minor point, I also don't think the situation is
quite as rare as you make out(*).

As we have now seen, such a change can only be made after very careful
consideration and thorough discussion in the programmer community.

Cheers,
Bent D


*) C code in string literals is not necessary, it was a consequence of
my example being based on the notion of the programmer commenting out
parts of his code to try an alternative. The same problem would
manifest itself with e.g.
/* these are the operators supported
/* by our calculator */
char* operators = "+-*/=";
 
S

Stefan Ram

Thomas Pornin said:
So the "#if 0" is from early C days, while "if (0)" is the new,
reformed way. Apparently, Sun chose to follow Ritchie's ideas
in that matter.

In the real early days, there was no »#if«, only »#define«
and »#include«.

I believe, then, there was a time, when there was »#ifdef«,
but no »#if«, but I failed to verify this using records.

I do not know how much the ideas of Dennis Ritchie influenced
the C preprocessor. It was introduced in 1972/3 »partly at the
urging of Alan Snyder, but also in recognition of the utility
of the the file-inclusion mechanisms available in BCPL and
PL/I«, »Soon thereafter, it was extended, mostly by Mike Lesk
and then by John Reiser, to incorporate macros with arguments
and conditional compilation.«
 
W

Wojtek

blue indigo wrote :
- But it takes a lot more typing to insert "// " at the start of each of
1000 lines than to insert "/*<RET>" at the top and "*/<RET>" at the bottom.

Select, CTRL-/

At least in most modern IDEs. Heck, even the Visual Basic editor from
1999 has this.
 
R

Roedy Green

Test01.java:4: exception java.io.IOException is never thrown in body
of corresponding try statement
try {} catch (java.io.IOException e) {}

I too find that annoying. I would like to build a catch, especially
into in interface for an exception I MIGHT want some day.

However, if you use an IDE like IntelliJ Idea, it fairly easy to add
them later. This keep the code simpler.
--
Roedy Green Canadian Mind Products
http://mindprod.com

"By 2040, the Sahara will be moving into Europe, and Berlin
will be as hot as Baghdad. Atlanta will end up a kudzu
jungle. Phoenix will become uninhabitable, as will parts of
Beijing (desert), Miami (rising seas) and London (floods).
Food shortages will drive millions of people north, raising
political tensions."
~ James Lovelock
Lovelock is more pessimistic than the consensus, because he thinks man will
refuse to take significant action to ameliorate global warming.
 
D

Daniel Pitts

blue said:
That must rank up there on the "all-time top 100 boneheaded decisions"
list. "Such comments do not nest," that is. They even have a distinct left
and right delimiter, so it would have been trivial to make them nest
appropriately, and doing so would have made it very easy to comment out
large blocks of code containing pre-existing comments. Yet they did not,
probably out of sheer laziness.

// comments were introduced to C++ (and later backported to C) partly to
address this, only to run into their own problems:

- You can now use /* */ to easily comment out a lot of code containing
only // comments.
- You can now use // to comment out a lot of code containing arbitrary types
of comments.
- But it takes a lot more typing to insert "// " at the start of each of
1000 lines than to insert "/*<RET>" at the top and "*/<RET>" at the bottom.

Better would have been to require /* */ comments to nest properly in C++,
and eventually backport THAT to C. It wouldn't have even broken anything,
since */ is not legal outside of a comment, so changing the parsing rules
for comments in the appropriate manner wouldn't have caused valid code to
suddenly become comments in pre-existing compilable code.

Java would have benefited too, since it inherited the C++ system of
commenting syntax.

It could have broken a lot, actually. I often used mismatched starting
comments on purpose while testing:

I'm willing to bet that such code has made it into production systems.
Changing the meaning of "/* /* */" would break that code, sometimes
without any warning.

doSomething();
// I can easily toggle doSomethingElse and doSomeOtherThing() call by
// adding a */ at the end of the following line
/*
doSomethingElse();
doSomeOtherThing(); /**/
doSomeFinalThing(); // */

Before the change, doSomethingElse, and doSomeOtherThing are ignored,
but if you added nesting, doSomeFinalThing would also be ignored,
without any notice from the compiler.
 
A

Arne Vajhøj

Roedy said:
I too find that annoying. I would like to build a catch, especially
into in interface for an exception I MIGHT want some day.

Classes do not have to throw all exceptions declared in their
interface.

Arne
 
A

Arne Vajh¸j

blue said:
Yes, of course it would have to take quotation marks into account as
well as /* and */.

I thought that went without saying, sorry mate.

The corner case you point out ought to be rare in practise. How common is
it for string literals containing C source to occur in C source? Outside
of quines and IOCCC submissions, anyway.

Changes that impact existing code are generally frowned at no matter
if it is 10%, 0.1% or 0.001% of existing program that will be
impacted.

Arne
 
A

Arne Vajh¸j

blue said:
That must rank up there on the "all-time top 100 boneheaded decisions"
list. "Such comments do not nest," that is. They even have a distinct left
and right delimiter, so it would have been trivial to make them nest
appropriately, and doing so would have made it very easy to comment out
large blocks of code containing pre-existing comments. Yet they did not,
probably out of sheer laziness.

It would have meant a fundamental change compared to C. C compatibility
was obviously a goal.
Better would have been to require /* */ comments to nest properly in C++,
and eventually backport THAT to C. It wouldn't have even broken anything,
since */ is not legal outside of a comment,

It is valid with / as start of a comment.

a = a */* multiply with 2 */ 2;

is valid C.

Arne
 
M

Mike Schilling

Arne said:
Classes do not have to throw all exceptions declared in their
interface.

For obvious reasons.

interface Storage
{
void store(byte[] data) throws IOException;
...
}

class NullDevice implements Storage
{
public void store(byte[] data)
{
return;
}
}
 
L

Lew

Arne said:
Changes that impact existing code are generally frowned at no matter
if it is 10%, 0.1% or 0.001% of existing program that will be
impacted.

I just got bitten by a Java 6 change that broke existing code.

We have a bunch of things that rely on a library that has classes that
implement java.sql.Statement.
<http://java.sun.com/javase/6/docs/api/java/sql/Statement.html>

The library is compliant with Java 5. We compile it from source. The
interface has methods that were added in Java 6, so the code doesn't compile
under Java 6.
 
S

Steve Wampler

Lew said:
I just got bitten by a Java 6 change that broke existing code.

And I've got code where Integer.parseInt(s) is now throwing a
different exception. The change took place between jdk 1.6.0_10
and jdk 1.6.0_12. My suspicion is that something that was broken
has now been fixed - and the code was written based on the broken
behavior.
 
B

blue indigo

This then becomes a considerably more complex change than what you
outline above and one that is sure to meet with, shall we say,
spirited debate in the larger C community.

So, tracking two sets of delimeters is "considerably more complex" than
tracking one. I did not know that. Thanks.
That is really of no interest whatsoever. All that needs to be
demonstrated is that there can exist code that will break after the
change and such a demonstration, however eccentric, is sufficient to
disprove the claim that the change can safely be introduced with no
further ado. As a minor point, I also don't think the situation is
quite as rare as you make out(*).

As we have now seen, such a change can only be made after very careful
consideration and thorough discussion in the programmer community.

Considering that I had suggested that C should have done this from the
outset, before there was any C code to break, and failing that that C++
should have (and C++ had numerous other minor differences from C from the
outset, that would break a bit of the existing C codebases if compiled as
C++), and failing that that Java should have, this isn't really all that
important.
*) C code in string literals is not necessary, it was a consequence of
my example being based on the notion of the programmer commenting out
parts of his code to try an alternative. The same problem would
manifest itself with e.g.
/* these are the operators supported
/* by our calculator */
char* operators = "+-*/=";

Quote-counting fixes this, as I noted in my previous post. This sort of
code is not especially common, either -- and consider that if five symbols
are listed in arbitrary order, the odds that a particular two will happen
to be adjacent and in a particular order are not particularly high.

In fact, consider the permutations of "12345". There are 5! = 720 of
these. Of these, there are 3! = 6 that begin with "12" and permute only
the "345" at the end. All the permutations that keep 1 and 2 together are
ibtained from these permutations by compounding with an additional cyclic
permutation. There are five such cyclic permutations, but one of the five
splits the "12" up as so: "2xxx1". So there are only 6*4=24 permutations
that have "12" as a substring. That is 1/30th of 720. Not really unlikely,
but somewhat bad luck, comparable to rolling snake eyes.

Another permutation of that string is even more interesting in light of
this debate, though: "+-/*=". (And 23 of its friends.) The C preprocessor
or javac _already_ needs to count quotation marks in order to avoid the /*
internal to that string literal acting as a comment start, using the
_present_ comment parsing rules.

Daniel Pitts had a different sort of corner-case, not involving string
literals:
doSomething();
// I can easily toggle doSomethingElse and doSomeOtherThing() call by
// adding a */ at the end of the following line
/*
doSomethingElse();
doSomeOtherThing(); /**/
doSomeFinalThing(); // */

I consider that kind of fiddly stuff to be an antipattern. #if(DEBUG) is
far, far better, much cleaner and more readable. Moreover, in the specific
case of Java it is not even applicable.
 
B

Bent C Dalager

So, tracking two sets of delimeters is "considerably more complex" than
tracking one. I did not know that. Thanks.

You're welcome.
Considering that I had suggested that C should have done this from the
outset (...)

I did not comment on that, my comment was directed at the suggestion
that a retroactive change to accomplish this would be unproblematic.

What C ought to have done from the very beginning is a different
debate.
(...) This sort of
code is not especially common, either -- and consider that if five symbols
are listed in arbitrary order, the odds that a particular two will happen
to be adjacent and in a particular order are not particularly high.

(...)

Daniel Pitts had a different sort of corner-case, not involving string
literals:

(...)

I consider that kind of fiddly stuff to be an antipattern. #if(DEBUG) is
far, far better, much cleaner and more readable. Moreover, in the specific
case of Java it is not even applicable.

If you had made it clear from the start that your suggestion
/actually/ was "if everyone had written C code in some as yet to be
disclosed manner of my own invention then retroactively making this
change would not have been a problem" - we would not be having this
debate.

Cheers,
Bent D
 

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,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top