Re: Variable naming problem



Stefan Schulz wrote:
> Maybe we should talk about what constitutes a failure first. For me, a
> failure is a condition the programmer can not reasonably expect or be
> expected to deal with. For example, when writing to a file, it is not
> reasonable to require the programmer to check before each invocation of
> write() if the file he/she is writing to exists, is accessible, open
> for writing, that the harddisk does have sufficient space remaining,
> and so on.

If you define failures in that way, then don't all exceptions become
fatal, since by definition they cannot be handled? I think a more
reasonable approach is to recognize that certain conditions cannot be
handled right away in the local scope, and so someone higher up on the
stack needs to sort it out. For example, if we get a FileNotFound
exception, the class responsible for handling a file may have no
reasonable way to ameliorate the situation, but the GUI sitting on top
of it can just query the user for different input.

That's what exceptions are useful for -- indicating error conditions
that, by their nature, "want" to unwind the stack and be dealt with at
a higher level. By contrast, some error conditions are almost always
more appropriate to handle locally. In some of these cases, a simple
return value is perfectly adequate and provides the previously-noted
benefits of efficiency and conciseness.

> However, most data streams reach their end eventually, and pretty
> often, this is nothing to worry about either. This is not a failure
> (and therefore, not where you would use an exception), for the most
> part. However, if you know your file contains base64-encoded data, and
> ends in midst of a quartet, this becomes a failure, since an assumption
> you made is violated.

It's nothing to worry about; it just requires appropriate logic to deal
with it, and that logic is separate from the logic applied when the
stream has not yet ended. I think it's fair to call it a failure for a
simple reason: based on just the name "readLine," when I call the
method I expect it to read a line. If it does not do so (e.g. EOF), it
has failed to read a line. It's not a moral judgement against the poor
method, just a statement that it did not perform its advertised
function.

You might be interested to read a column I found very enlightening:
http://www.gotw.ca/gotw/061.htm
The series of articles is oriented towards C++, but this article in
particular applies just as well to Java. The author applies the ACID
paradigm (Atomic, Consistent, Isolated, Durable) from database
transactions to error safety. In the presented notation, a lower-case
'a' indicates that the operation is all-or-nothing; if it fails,
program state is unchanged. An upper-case 'A' is a stronger guarantee,
and indicates that the operation is guaranteed to succeed. One could
still argue that, on reaching EOF, readLine() can still "succeed" by
"successfully returning false," but I think that's stretching it.
Unless readLine() always, always, always reads a line successfully,
it's not capital-A Atomic, which means it sometimes fails.

> > What reasonable behavior could isEmpty() have?
>
> Maintain an access timestamp, for example? It might also release
> "backing store", shrink internal arrays, and so on.

Sure, but that's still housekeeping, not changing the logical state.
Should I say "overt behavior?" "Visible behavior?"

> This highly depends on what you expect of your lines. If a "valid" line
> is always terminated by some sequence (say "\r\n"), neither is a good
> implementation (you should both return a boolean, and possibly throw
> the exception). However, if the last line of your input stream may just
> stand on its own, then the former is the right one.

Ah, this brings up a very good point -- what to do in the case where
both serious errors (e.g. malformed data, the sort of thing which
requires a recovery action and is likely to want stack unwinding) and
non-problematic failures (readLine didn't read a line, indicating end
of input) can occur. One could write separate catch blocks for each,
but is it really good to treat them the same?

> We seem to talk on cross purposes. I do not advocate exceptions for
> control flow. That would really be using a hammer to hand out chicken
> soup. However, failures (as in behaviour you are not prepared and
> should not have to be prepared to handle) should not be signalled by a
> return value - it is too easily ignored or forgotten.

I think we're on the same page -- it's worth discussing further what is
an appropriate definition of "failure" (as discussed above), but
there's no point chasing any further down the path of what happens when
we use different definitions -- the result is obvious. :)

I'm particularly interested in what you think of the above idea of
exceptions as errors that want to propagate upwards, versus local
failures that can be handled by retries, terminating loops, etc.

Luke

.



Relevant Pages

  • Re: whodunnit: motherboard dead
    ... You are correct that static electricity probably is not ... Just not a more likely reason for failure. ... supply manufacturer provide a long list of numerical specs. ...
    (sci.electronics.basics)
  • Re: system return value makes for strange logic
    ... %%> of the failure. ... %% The reason is that systemreturns the exit status of the program it runs. ... %% exits with 0 on success and any number of non-zero values upon failure. ... that fails sets $? ...
    (comp.lang.perl.misc)
  • Re: Knackered crank?
    ... they decided to change it - the main reason ... Because it is a catastrophic failure, ... is in effect a 5" lever (pedal load from the spindle) bending it while ... And now, Octalink is another abandoned Shimano standard, ...
    (rec.bicycles.tech)
  • Re: Problems with export of mails with Outlook 97
    ... it will be corrupt beyond repair. ... That is one of many reason we advise against exporting and importing to ... transfer Outlook data. ... >>> thus the failure message may not be exactly wordwise). ...
    (microsoft.public.outlook)
  • Re: Thread Pre-Emption Question . . .
    ... Not checking for failure of InitializeCriticalSection, ... not checking deallocateor failure is okay because the program will continue to run correctly although it is good practice to check this in debug builds because deallocators usually only fail because of invalid arguments. ... the correct execution of error handling logic (if the access causes unplanned exceptions before data corruption and these unplanned exceptions are caught in the same place as planned exceptions for example). ... This can, and will, corrupt real data in any number of random ways depending on the work done in the writer. ...
    (microsoft.public.win32.programmer.kernel)