a criticism of java

P

Patrick May

I missed the original post but I disagree with the point that if the
file exists, you don't need to worry about a
FileNotFoundException. Many of us work in multiuser
environments. The file could be deleted right after you check for
its existence. Is this likely? Probably not. But in some
environments it could happen.

For the record, I agree with you. The original poster suggested
eliminating those exceptions, which would indeed significantly impact
the resiliency of the system.

My point was that a decent macro capability would allow the
programmer to increase legibility without reducing resiliency.
It would be great if Java had macro capabilities like Lisp and I
will look at the link. I haven't touched CL since grad school but it
was very cool. There are only 2 things I dislike about Lisp. The
parentheses are a pain (I got used to them)

Parentheses in Lisp are like anti-Fnords. When you no longer
notice them, you have reached enlightenment.
and it's not very marketable.

But what it enables is _very_ marketable.

Regards,

Patrick
 
D

Dag Sunde

yes, that's another thing in java that would make me mad.
Why can't java let you just test if a file exists, if(theFile.exists())
{ read it }

Eh...?

boolean exists = (new File("Filename")).exists();
 
D

Dimitri Maziuk

(e-mail address removed) sez:
....
Thanks. I'd alway thought that people that criticised exceptions were
bludgeoned to death by the java police.

"It's better than testing for error codes"
"If you had programmed in C or C++, you'd see that Exceptions are much
better than the alternative"

Well, you've got to agree that
a) people don't test for error codes even when they should've,
b) there is no "generic error code" from a function that returns
a signed int (see also two's complement),
c) consolidating all "catch" code into last code pages that will
(hopefully) never need to be even swapped in is a Good Thing(tm)
performance-wise.

(Speaking of a), they could force people to at least pop function's
return value from stack, making it harder to ignore -- and getting
overloading on return value as a bonus -- but that'd make it look
too much like Pascal. Too scary to contemplate.)
"This whole mandatory exception thing, forcing people to check their
code, is a really good idea"

Declare "myfunc() throws Exception" if you don't want to care.

What ticks me off is that Java's taking it too far in assuming
that any error is "exceptional". E.g. (last time I checked)
boolean isInt( String s ) {
try { Integer.parseInt( s ); return true; }
catch( NumberFormatException e ) { return false; }
}
is orders of magnitude slower than checking if s[0] is a plus, dash,
or digit, and s[1..n] are digits -- on input consisting of mostly
non-integer strings. Which is fine if non-integer input strings are
"exceptionally rare errors" in your problem domain, but IRL you tend
to get data with "unk", "n/a", "?", etfc. all the time. (Of course,
last I checked none of parseXXX()'s thought 1e2 was a valid number
so they were never much use anyway.)

Dima
 
Q

q_q_anonymous

Dimitri said:
(e-mail address removed) sez:

Well, you've got to agree that
a) people don't test for error codes even when they should've,

but if a programmer is that bad then exceptions won't make him into a
good programmer. It might make his program bad rather than aweful. And
this is no excuse for making the language horrible. I don't think this
was the intention for exceptions anyway, 'cos it'd be a silly reason.
b) there is no "generic error code" from a function that returns
a signed int (see also two's complement),

the fact that a function like parseInt cannot really return an integer
when there's an error. You yourself point out the absurdity of using
this as an excuse for a (long winded) Exception, since as you say, it's
easy to use a boolean function or expression to test for a non integer,
and it's not exactly an exception.
So, better to test for it with a boolean expression. Then, if parseInt
is executed on a non integer, let the program croak. Nothing caught,
it's programmer error. Exceptions aren't or catching programmers'
errors!
It's good for a programmer to test for his own errors, e.g. JUnit, but
not catch them, writing recovery code!
c) consolidating all "catch" code into last code pages that will
(hopefully) never need to be even swapped in is a Good Thing(tm)
performance-wise.

(Speaking of a), they could force people to at least pop function's
return value from stack, making it harder to ignore -- and getting
overloading on return value as a bonus -- but that'd make it look
too much like Pascal. Too scary to contemplate.)


Declare "myfunc() throws Exception" if you don't want to care.

That's meant to be bad practice, but, all the sources that say it's
bad practice, say so in the context of a person using it because he
isn't concerned about the exceptions his methods throw and doesn't
understand them.
But maybe it's not such a bad idea. If any exceptions go off that I
didn't write a try/catch for, then let the program croak, I want it to,
because it's a programmer error. Seems good . Strange that 'throws
Exception' is so frowned upon!
It should go with a comment that says the Exceptions the method can
throw. To give some understanding of the code i've done to avoid
exceptions being thrown.

What ticks me off is that Java's taking it too far in assuming
that any error is "exceptional". E.g. (last time I checked)
boolean isInt( String s ) {
try { Integer.parseInt( s ); return true; }
catch( NumberFormatException e ) { return false; }
}
is orders of magnitude slower than checking if s[0] is a plus, dash,
or digit, and s[1..n] are digits -- on input consisting of mostly
non-integer strings. Which is fine if non-integer input strings are
"exceptionally rare errors" in your problem domain, but IRL you tend
to get data with "unk", "n/a", "?", etfc. all the time. (Of course,
last I checked none of parseXXX()'s thought 1e2 was a valid number
so they were never much use anyway.)

Dima

YEAH! I absolutely agree with you.
Have a boolean expression test if it's an integer.
then Run Integer.parseInt on it and if it's not na integer, let the
program croak. That goes with the 'throws Exception' philosophy -
allowing Exceptions to be thrown like that but retaining presence of
mind, knowing waht can be thrown and knowingly letting them - with good
reason!

I would still throw an IllegalArgumentException with every method, -
not intended to be caught. Including a String describing the mistake.
For somebody to call a method without testing the arguments they pass
to it, relying on the method they call to test whether their arguments
are valid, then getting an IllegalArgumentException from the method
telling them what argumetn was invalid, and them catching it, and
writing error recovery code, is ridiculous. If they can put error
recovery code in a catch - which is rather late - then they can put it
early before they call the method!
 
H

Hendrik Maryns

(e-mail address removed) schreef:
I would still throw an IllegalArgumentException with every method, -
not intended to be caught. Including a String describing the mistake.
For somebody to call a method without testing the arguments they pass
to it, relying on the method they call to test whether their arguments
are valid, then getting an IllegalArgumentException from the method
telling them what argumetn was invalid, and them catching it, and
writing error recovery code, is ridiculous. If they can put error
recovery code in a catch - which is rather late - then they can put it
early before they call the method!

I suppose you aren´t a fan of design on contract either?

H.
--
Hendrik Maryns

==================
www.lieverleven.be
http://aouw.org
 
O

Oliver Wong

Dimitri Maziuk wrote:
[snip]
b) there is no "generic error code" from a function that returns
a signed int (see also two's complement),

the fact that a function like parseInt cannot really return an integer
when there's an error. You yourself point out the absurdity of using
this as an excuse for a (long winded) Exception, since as you say, it's
easy to use a boolean function or expression to test for a non integer,
and it's not exactly an exception.
So, better to test for it with a boolean expression. Then, if parseInt
is executed on a non integer, let the program croak. Nothing caught,
it's programmer error. Exceptions aren't or catching programmers'
errors!

You're saying writing code like this is stupid:

<stupidCode>
if (isInt(string)) {
try {
int x = parseInt(string);
} catch(NumberFormatException e) {
System.out.println("Oops, I guess this isn't an int after all.");
}
} else {
System.out.println("Not an int!");
}
</stupidCode>

and you're right! It is stupid. Instead, you should write code like this:

<betterCode>
try {
int x = parseInt(string);
} catch(NumberFormatException e) {
System.out.println("Not an int!");
}
Have a boolean expression test if it's an integer.
then Run Integer.parseInt on it and if it's not na integer, let the
program croak. That goes with the 'throws Exception' philosophy -
allowing Exceptions to be thrown like that but retaining presence of
mind, knowing waht can be thrown and knowingly letting them - with good
reason!

That's akin to this:

<code>
if (isInt(string)) {
try {
int x = parseInt(string);
} catch(NumberFormatException e) {
/*
string must be parseable because we checked it just a few moments ago.
*/
throw new Error("This should never happen.");
}
} else {
System.out.println("Not an int!");
}
I would still throw an IllegalArgumentException with every method, -
not intended to be caught. Including a String describing the mistake.
For somebody to call a method without testing the arguments they pass
to it, relying on the method they call to test whether their arguments
are valid, then getting an IllegalArgumentException from the method
telling them what argumetn was invalid, and them catching it, and
writing error recovery code, is ridiculous. If they can put error
recovery code in a catch - which is rather late - then they can put it
early before they call the method!

IllegalArgumentException is an unchecked exception, and unchecked
exceptions are NOT meant to be caught. You are SUPPOSED to let the program
"just croak". In other words, Java is already designed with this in mind.

- Oliver
 
Q

q_q_anonymous

Hendrik said:
(e-mail address removed) schreef:


I suppose you aren´t a fan of design on contract either?

You mean strictly defining what goes in and out of the method - so the
method is designed to fulfill a contract with its user ? Of course I
believe in that.

I would test the arguments very carefully and throw
IllegalArgumentExceptions if they screw up. I consider them calling my
method with illegal arguments to be them screwing up - programmer
error.

I'm not sure what text I wrote could have possibly led you to believe
what you wrote.
 
H

Hendrik Maryns

(e-mail address removed) schreef:
You mean strictly defining what goes in and out of the method - so the
method is designed to fulfill a contract with its user ? Of course I
believe in that.

I would test the arguments very carefully and throw
IllegalArgumentExceptions if they screw up. I consider them calling my
method with illegal arguments to be them screwing up - programmer
error.

I'm not sure what text I wrote could have possibly led you to believe
what you wrote.

Well then you should know that the method signature is a part of the
contract, so adding unnecessary throws declarations is just making the
contract less attractable. You talk about documenting when which errors
can be thrown, why not do part of that in the method signature? This
can be formalised, by using the @throws clause, but if you are going to
have to describe every possible exception there, you will have more work
describing them than writing some more (robust) code which will actually
handle the exceptions.

H.

--
Hendrik Maryns

==================
www.lieverleven.be
http://aouw.org
 
Q

q_q_anonymous

Oliver said:
Dimitri Maziuk wrote:
[snip]
b) there is no "generic error code" from a function that returns
a signed int (see also two's complement),

the fact that a function like parseInt cannot really return an integer
when there's an error. You yourself point out the absurdity of using
this as an excuse for a (long winded) Exception, since as you say, it's
easy to use a boolean function or expression to test for a non integer,
and it's not exactly an exception.
So, better to test for it with a boolean expression. Then, if parseInt
is executed on a non integer, let the program croak. Nothing caught,
it's programmer error. Exceptions aren't or catching programmers'
errors!

You're saying writing code like this is stupid:

<stupidCode>
if (isInt(string)) {
try {
int x = parseInt(string);
} catch(NumberFormatException e) {
System.out.println("Oops, I guess this isn't an int after all.");
}
} else {
System.out.println("Not an int!");
}
</stupidCode>

and you're right! It is stupid. Instead, you should write code like this:

<betterCode>
try {
int x = parseInt(string);
} catch(NumberFormatException e) {
System.out.println("Not an int!");
}
</betterCode>


I'm glad you gave a code example, it clarifies. That wasn't what I
meant. I"ll show you the code I meant.

I'd rather Integer.parseInt threw an IllegalArgumentException, but
since it throws a checked Exception, i'll add a throws Exception to the
method header.
I won't add a thows numberFormatException to the header because if that
is thrown, it's my programming error for passing what i'd consider an
IllegalArgument to parseInt. I wouldn't expect somebody else to catch
it.


This is what I meant

public void methodX() throws Exception
{
....
if (isInt(string))
int x = parseInt(string);
else
System.out.println("Not an Int");
}





I notice I have beef with NumberFormatException thrown bY parseInt -
which I would try to ensure isn't thrown and would never catch (if it
wre thrown it'd be my programming error).

I have some beef with FileNotFoundException thrown by readLn (which I
don't always want to catch). So, I think that's fine being thrown, but
it should be unchecked.
So maybe it's Checked Exceptions I have beef with, because sometimes
they should be IllegalArgumentExceptions , and sometimes, I don't want
to catch them - I wnat the program to crash-exit.






That's akin to this:

<code>
if (isInt(string)) {
try {
int x = parseInt(string);
} catch(NumberFormatException e) {
/*
string must be parseable because we checked it just a few moments ago.
*/
throw new Error("This should never happen.");
}
} else {
System.out.println("Not an int!");
}
</code>

Interesting interpretation! But No.

The code I wrote in this post illustrates. When I said 'throws
Exception philosophy' i was talking about putting that in the method
header, for reasoons written above - in this post. The only Exception I
speak of manually throwing is the (unchecked) IllegalArgumentException.


IllegalArgumentException is an unchecked exception, and unchecked
exceptions are NOT meant to be caught. You are SUPPOSED to let the program
"just croak". In other words, Java is already designed with this in mind.

Yes, thanks, that makes good sense.

I guess my isuee is with Checked Exceptions.
 
Q

q_q_anonymous

Hendrik said:
(e-mail address removed) schreef:

Well then you should know that the method signature is a part of the
contract,

not the way I am using it. The throws Exception isn't saying this
method WILL throw anything. It doesn't actually change what the method
throws. It does mean that the code within the method reads a lot
better.

in a single user system, a FileNotFoundException while i'm reading a
small file is very exceptional. And I won't be dealing with it. Just
like I won't be dealing with an Out Of Memory Exception. As far as
I'm concerned, it should be unchecked.

So the throws Exception is a orkaround for the problem that i'd like
FileNotFoundException and NumberFormatException should be unchecked
exceptions. Really, i'd like Integer.parseInt to throw an
IllegalArgumentException if I passed it a String. And i'd like
FileNotFoundException to be an unchecked, because in my patricular
case, I dont' want to recover from it. (I deal with the file not
existing before I start reading it, but if it vanishes while reading
from it then I personally would let the program crash exit).

If the user really wants to, he can recover from it. But I am the main
user of the method, and I can comment that the FileNotFoundException
isn't thrown, and I am writing the method for users that don't
typically want to recover from it.
If they want to it's no problem, they can write their own catch.
Just like they can for any other unchecked Exception ilke out of
memory exception, or any exception that is outside the programmer's
control.


so adding unnecessary throws declarations is just making the
contract less attractable.

The way i'm using the throws, it shouldn't be read as part of the
contract. It makes no difference to the existing contract. It says
nothing extra. It just says this method could throw an Exception.
It makes the code inside the method a lot neater, and the code is just
as strong. THe purpose of the throws clause is not for the contract -
the way I use it , it says nothing.

You talk about documenting when which errors
can be thrown, why not do part of that in the method signature?

For the same reason that certain exceptions were made Unchecked. The
same reason that sun made sure you don't have to write Out of memroy
exception in the throws clause.or null pointer exception. These are
errors - I think - that are either outside of the programmer's control
and thep rogrammer may just want to have the program crash-exit or
they are programmer errors.

I am treating the NumberFormatException thrown by parseInt as an
IllegalArgumentException, and therefore, something which sun recognizes
is an unchecked exception and wouldn't be declared, because if it were
thrown, it'd be programmer error. You don't write code to recover from
them. You crash-exit

In a typical situation, you woudln't catch these , so I wouldn't
declare them and inconveniene the user of the method.
If he wants to catch them, he can

This
can be formalised, by using the @throws clause, but if you are going to
have to describe every possible exception there, you will have more work
describing them than writing some more (robust) code which will actually
handle the exceptions.

I'm talking about Exceptions that either shoudl be
illegalargumentexceptions or - the way I am using the method - should
be unchecked.

sun recognizes exceptions like this. calls them unchecked exceptions.
 
D

Dimitri Maziuk

(e-mail address removed) sez:
....
I notice I have beef with NumberFormatException thrown bY parseInt -
which I would try to ensure isn't thrown and would never catch (if it
wre thrown it'd be my programming error).

I have some beef with FileNotFoundException thrown by readLn (which I
don't always want to catch). So, I think that's fine being thrown, but
it should be unchecked.
So maybe it's Checked Exceptions I have beef with, because sometimes
they should be IllegalArgumentExceptions , and sometimes, I don't want
to catch them - I wnat the program to crash-exit.

Well, with exists( file ) all you get from "test-then-(open-or-throw)"
vs. "open-or-throw" is an extra test that doesn't guarantee anything
anyway, so you might as well skip it.

Also e.g.
if( exists( file ) )
open( file ) // -- OK if program crashes here

But
do
tempname = generate_random_name()
while( exists( tempname ) )
open( tempname ) // -- does not crash
...

In this case 2 processes may well write to a single temp. file.
They crash much later when they try to read the file back in, and
that's not what you want.

Dima
 
O

Oliver Wong

[snip]
I guess my isuee is with Checked Exceptions.

Okay, I had earlier thought you wanted to "ban all exceptions" or
something. Anyway, if that's your main beef with Java, you might like C#.
They're relatively similar, but ALL exceptions in C# are unchecked.

- Oliver
 
H

Hendrik Maryns

I think it all boils down to a different point of view, and neither of
us will convince the other, so you may read the rest of my reply, or
just ignore it. Sorry for the top-post.

(e-mail address removed) schreef:
not the way I am using it. The throws Exception isn't saying this
method WILL throw anything.

Indeed, it only warns that the method /could/ throw that particular
exception. And if you take DBC seriously, you will mention in the docs
under what circumstances that is possible. Thus, the example you gave
in another post:

public void methodX() throws Exception
{
....
if (isInt(string))
int x = parseInt(string);
else
System.out.println("Not an Int");
}

is rather ridiculous, as now you have to bother the client of the method
with reading that you do declare an exception can be thrown, but then
you document that actually, it can´t. Why not just put a try/catch
around it and not bother the client of your method?

It doesn't actually change what the method
throws. It does mean that the code within the method reads a lot
better.

I think the code within a method is much less important than that what
the client gets to see, i.e. the method signature and the documentation.
in a single user system, a FileNotFoundException while i'm reading a
small file is very exceptional. And I won't be dealing with it. Just
like I won't be dealing with an Out Of Memory Exception. As far as
I'm concerned, it should be unchecked.

Ok, but a single user system is not what Java was built for, and for
much applications is not the rule, but the exception.

Funny thing is, there are others that claim UNchecked exceptions are a
misdesign... (and I tend to agree with them, I always document when a
method might throw an NPE or IAE or ...)
So the throws Exception is a workaround for the problem that i'd like
<snip>
Indeed, good for a one-person program, which once again is not the rule
but the exception.
If the user really wants to, he can recover from it. But I am the main
user of the method, and I can comment that the FileNotFoundException
isn't thrown, and I am writing the method for users that don't
typically want to recover from it.

And you are sure you will never have to hand over your code to another
maintainer?
If they want to it's no problem, they can write their own catch.
Just like they can for any other unchecked Exception ilke out of
memory exception, or any exception that is outside the programmer's
control.

The way i'm using the throws, it shouldn't be read as part of the
contract.

But unfortunately, it is.

It makes no difference to the existing contract. It says
nothing extra. It just says this method could throw an Exception.
It makes the code inside the method a lot neater, and the code is just
as strong. THe purpose of the throws clause is not for the contract -
the way I use it , it says nothing.

But how is your client supposed to know that? Probably because you
document it, but then that is just as much work, no?
For the same reason that certain exceptions were made Unchecked. The
same reason that sun made sure you don't have to write Out of memroy
exception in the throws clause.or null pointer exception. These are
errors - I think - that are either outside of the programmer's control
and thep rogrammer may just want to have the program crash-exit or
they are programmer errors.

You have a point, and there would be no need for many of those
exceptions if there was a precondition system that checked for null
values and the like. (Maybe I really should switch to Eiffel)
I am treating the NumberFormatException thrown by parseInt as an
IllegalArgumentException, and therefore, something which sun recognizes
is an unchecked exception and wouldn't be declared, because if it were
thrown, it'd be programmer error. You don't write code to recover from
them. You crash-exit

Depending on how robust you want your program, even if it is an
auxiliary class. Robustness vs. efficiency, the usual dilemma, right?


--
Hendrik Maryns

==================
www.lieverleven.be
http://aouw.org
 
Q

q_q_anonymous

Hendrik said:
I think it all boils down to a different point of view, and neither of
us will convince the other, so you may read the rest of my reply, or
just ignore it. Sorry for the top-post.

The throws clause is part of the language and not an effective tool for
documenting the method. If you use it as such, then you have to deal
with the fact that it doesn't demand listing 'unchecked exceptions'*,
and doesn't list preconditions and postconditions.
Documentation should be in English rather than java code that wasn't
intended for that!

(* I personally wouldn't document all kinds of unchecked exceptions.
Cerainly not programmer errors. Maybe some related to outside
environment though. )


Not having checked exceptions declared in those instances as I
suggested, will not make the program less robust. If they are
declared, as you would. Or if they are not declared as I would, it
still means that we're not dealing with it.

In the rare event that the user will deal with an unchecked exception
(and they are rare hence the exception is unchecked).
In that rare event, the user may catch the exception, he has the
choice to do so, but he is not forced to catch or declare it. To
force the programmer to do so, is a self imposed restriction that comes
at too great a cost. It's absurd to list all the unchecked exceptions
in the throws clause, as you suggest. Especially programmer errors
within the method, like NullPointerException. Do you think the user of
the method is going to see that and think "arr, I forgot that might be
throw, I might want to catch it". The user of the method should be
aware that exception may be thrown. Checked exceptions come at a great
cost.

A programmer that isn't absolutely aweful, can write robust code with
just unchecked exceptions. He doesn't have to be forced to catch one
or to declare every unforeseen possibility in java code. possibilities
which will rarely be dealt with, but can be dealt with even without him
listing them in java code. His only excuse is he is abusing it as a
documentation tool, that is crazy. It's java code!


How about writing good code, and good documentation ! And not try to
include documentation in a throws clause, cluttering the method header,
cluttering the method body. And, as I said. Documentation shouldn't be
in java code. so, i'm not saying it shouldn't be in non english.
Efforts are being made in academic circles to use mathematical symbols
to document programs. e.g. to say that an array is sorted.
But the point is that java code isn't flexible enough to do this. It
wasn't built for documenting programs.

I am all for descriptive documentation, and that does take longer to
write.

I also put an IAE in the throws clause. Because I manually throw an IAE
with a descriptive String. It's not an unchecked exception that just
gets thrown due to my error or the outside environment. It's user
error, and I want him to know he can't get away with it! But this is no
replacement for proper documentation. I would never let my throws
clause document my program at the cost of my code Or at the cost of
causing unnecessary frustration to the user of the method!!
 
R

ricky.clarkson

The throws clause is part of the language and not an effective tool for
documenting the method.

Am I to take this to mean that documentation needs to duplicate the
source code?

/**
@param values an array of type int passed in using the varargs
syntax.
@return an int which is one of the passed in values.
*/
int giveOneBackAtRandom(int... values)
{
return values[(int)(Math.random()*values.length)];
}

It seems to me that the 'int' nature of the parameters and return type
is better expressed in the language. Now suppose I change this method
to use doubles:


/**
@param values an array of type int passed in using the varargs
syntax.
@return an int which is one of the passed in values.
*/
double giveOneBackAtRandom(double... values)
{
return values[(int)(Math.random()*values.length)];
}

I've got a mismatch between comment and code, caused by the comment
duplicating the code. Here is a better comment:

/**
@return one of the parameters, chosen at random.
*/

Much more concise, and as it happens, it's more useful too, because
earlier I was concentrating on filling in @param and @return, getting
the return type right, etc., and completely forgot to mention
randomness.
Efforts are being made in academic circles to use mathematical symbols
to document programs. e.g. to say that an array is sorted.

Why not use a SortedSet, or a custom implementation that wraps an array
or always making sure it is sorted? Then it will be blindingly obvious
that it's sorted, because it will be of type SortedArray or something.

The code should be as expressive as is practical, to enforce contracts.
That's the great advantage of static typing, we can have contracts.
In dynamically-typed languages, we can do stuff like:

/*
Adds the specified item to the specified list
*/
function push(var list,var item)
{
list.add(item);
}

Then someone comes along and types the parameters in the wrong order,
and ends up adding a list to a string instead of a string to a list.
The runtime doesn't notice. This is because the contract is not
expressed in code, it is expressed in documentation. Documentation
isn't as strict as a static-type-checking language:

public static <T> void push(final List<T> list,final T item)
{
list.add(item);
}

This not only catches the above bug, but prevents some other bugs, like
adding a Banana to a List<String>, for example. A real case I've seen
recently is a new programmer mixing up Strings and JTextFields, and
unfortunately using 1.4.

So if you need to specify part of the contract in documentation, you're
probably fighting the language or lamenting something you wish it had.
 
Q

q_q_anonymous

Am I to take this to mean that documentation needs to duplicate the
source code?

That wasn't what I meant, but what the advice you wrote is lucid and
wise.

Personally, I tend to write reams of notes for a method , and write it
outside the code, because it'd just make the code unreadable. I
wouldn't call it documentation since it's more notes to self, and I
wouldn't expect anybody else to read it until I tidy it up. It's more
whitebox notes.

I do write brief 'whitebox' notes in the code within the method too

But yes. Blackbox notes, just what goes in and out of the method, that
can be included in the code , and is a commentary on the method header.

I'm glad you posted this, because, although I wasn't disagreeing with
it, it has clarified things for me.

Blackbox documentation, is a commentary on the method header.
Thus, you are wise in - it seems to me - saying that the blackbox
documentation shouldn't duplicate what is written in the method header.
Like variable types.
And that strict typing helps document the code too, (as well as
preventing errors)


I was really only referring to after the throws clause. But I wasn't
even being that radical. No doubt that what is after the throws clause
is useful for documenting the method, but it shouldn't be adapted to
provide documentation for the method. I was debating with a guy that
appeared to me to not agree with unchecked exceptions, so he thought
that all exceptions should be checked, and thus would have no qualms in
listing all exceptions, including 'out of memory' exception and others,
on the end of a throws clause.
Declaring checked exceptions has ramifications. It's not necessarily
that I disagree with all checked exceptions. But those examples I gave
are from my short experiences with java, and those method shouldn't
have been throwing checked exceptions.



/**
@param values an array of type int passed in using the varargs
syntax.
@return an int which is one of the passed in values.
*/
int giveOneBackAtRandom(int... values)
{
return values[(int)(Math.random()*values.length)];
}

It seems to me that the 'int' nature of the parameters and return type
is better expressed in the language. Now suppose I change this method
to use doubles:


/**
@param values an array of type int passed in using the varargs
syntax.
@return an int which is one of the passed in values.
*/
double giveOneBackAtRandom(double... values)
{
return values[(int)(Math.random()*values.length)];
}

I've got a mismatch between comment and code, caused by the comment
duplicating the code. Here is a better comment:

/**
@return one of the parameters, chosen at random.
*/

Much more concise, and as it happens, it's more useful too, because
earlier I was concentrating on filling in @param and @return, getting
the return type right, etc., and completely forgot to mention
randomness.

you speak wisely
Why not use a SortedSet, or a custom implementation that wraps an array
or always making sure it is sorted? Then it will be blindingly obvious
that it's sorted, because it will be of type SortedArray or something.

That'd probably be better given the goal of sorting the array using the
java language.

But that'd just be as a demonstration for what can be done. I'm not an
academic, but i'm aware that there is work by Professor Bornat to prove
the correctness of programs using Hoare Logic. So no doubt it gets mroe
sophisticated than proving the correctness of a method to sort an
array.

The code should be as expressive as is practical, to enforce contracts.
That's the great advantage of static typing, we can have contracts.
In dynamically-typed languages, we can do stuff like:

/*
Adds the specified item to the specified list
*/
function push(var list,var item)
{
list.add(item);
}

Then someone comes along and types the parameters in the wrong order,
and ends up adding a list to a string instead of a string to a list.
The runtime doesn't notice. This is because the contract is not
expressed in code, it is expressed in documentation. Documentation
isn't as strict as a static-type-checking language:

indeed. I wouldn't make documentation a substitute for code or code a
substitute for documentation. But sometimes they complement one another
as you demonstrate. And the method header forms part of the
documentation, or the subject, of the documentation's commentary.

public static <T> void push(final List<T> list,final T item)
{
list.add(item);
}

This not only catches the above bug, but prevents some other bugs, like
adding a Banana to a List<String>, for example. A real case I've seen
recently is a new programmer mixing up Strings and JTextFields, and
unfortunately using 1.4.

So if you need to specify part of the contract in documentation, you're
probably fighting the language or lamenting something you wish it had.

Perhaps documentation within the code shouldn't duplicate what is in
the method header.
But I think that the chap I was discussing/debating with was lamenting
that unchecked exceptions weren't actually checked, and he might have
wanted to declare all of those.

I would say that they certainily shouldn't be written in the method
header. (java has unchecked exceptions - I believe with good reason).

He may write them in his documentation (though I wouldn't do that in
the 'in code' blackbox documentation - it wouldn't be brief enough to
be there).
It'd be in the exhaustive whitebox documentation that is mostly my
thoughts gathered together in a structured manner as I program.


And, my beef was with certain methods throwing checked exceptions when
I felt they should've been throwing unchecked exceptions. Thus, I
didn't want to be declaring them after the throws. If I were to
document that they are thrown, I'd write outside the source file, and
certainly not write them in the code. There are so many unchecked
exceptions.
I would not adapt the throws clause to provide documentation to a
checked exceptions that should really be unchecked.

Hence In those instances, I support not declaring them, by saying.

public int methodQ(String a) throws Exception
{
}



I would also manually throw the unchecked IllegalArgumentException,
and I might declare that, since I think that exception is very relevant
as a reminder to the programmer.


By the way. I see your understanding is lucid. Are you a teacher?
Do you recommend any particular book or sources of info for improving
my programming?

Where I see wisdom, I take advice. I see wisdom!
 
D

Dimitri Maziuk

Hendrik Maryns sez:
....
Ok, but a single user system is not what Java was built for, and for
much applications is not the rule, but the exception.

Funny thing is, there are others that claim UNchecked exceptions are a
misdesign... (and I tend to agree with them, I always document when a
method might throw an NPE or IAE or ...)

<snip>
Indeed, good for a one-person program, which once again is not the rule
but the exception.

Says who? I think if you examine your desktop computer closely,
you'll find that > 50% of applications there are inherently
single-user.

There's a whole lot of applications that are (or should be)
fault-oblivious: if something bad happens, they should just
crash. Because trying to recover gracefully and correctly is
not worth the trouble, if at all possible. Java gets quite
annoying if you're writing an application like that.

Dima
 
Q

q_q_anonymous

Oliver said:
[snip]
I guess my isuee is with Checked Exceptions.

Okay, I had earlier thought you wanted to "ban all exceptions" or
something. Anyway, if that's your main beef with Java, you might like C#.
They're relatively similar, but ALL exceptions in C# are unchecked.

- Oliver

Thank you, you have tempted me to check out C#. Originally I just
knew that exceptions bugged me, but thanks to your line of inquiry, I
have a more thorough understanding. I hope this thread is useful for
others that also became frustrated with Exceptions for the same
reasons. Your inquiry and code examples, really pinpointed the issue.
The other issue that they are long winded was neatly addressed by the
poster that mentioned the macro language. But, as you helped discern,
my problem was largely with certain methods throwing checked
exceptions. or checked exceptions generally. I now have a more
sophisticated understanding of java's language design, and C#'s.
 
E

EricF

Hendrik Maryns sez:
....

Says who? I think if you examine your desktop computer closely,
you'll find that > 50% of applications there are inherently
single-user.

How many of them are written in Java?
There's a whole lot of applications that are (or should be)
fault-oblivious: if something bad happens, they should just
crash. Because trying to recover gracefully and correctly is
not worth the trouble, if at all possible. Java gets quite
annoying if you're writing an application like that.

Than use another language. If I recall correctly, 1 of the design goals of
Java was to make the language robust. It forces you to consider errors, unlike
C or C++. I agree that exception handling can be annoying, but it keeps me out
of trouble if I use it correctly.

Eric
 
D

Dimitri Maziuk

EricF sez:
.... I think if you examine your desktop computer closely,
How many of them are written in Java?

I hear Sun has an entire desktop environment written in it.

....
....
Than use another language. If I recall correctly, 1 of the design goals of
Java was to make the language robust. It forces you to consider errors, unlike
C or C++. I agree that exception handling can be annoying, but it keeps me out
of trouble if I use it correctly.

Exceptions are a Good Thing(tm). Making exception part of method
signature -- not so much. You have to jump through hoops if you
want to just let it crash, you have to jump through hoops if you
want to overload on exception (e.g. read() method that throws
SQLException when backed by a DB, IOException when backed by flat
file, and no exception when backed by in-memory storage), etc.

Dima
 

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,780
Messages
2,569,611
Members
45,271
Latest member
BuyAtenaLabsCBD

Latest Threads

Top