HP3000-L Archives

December 2001, Week 4

HP3000-L@RAVEN.UTC.EDU

Options: Use Monospaced Font
Show Text Part by Default
Show All Mail Headers

Message: [<< First] [< Prev] [Next >] [Last >>]
Topic: [<< First] [< Prev] [Next >] [Last >>]
Author: [<< First] [< Prev] [Next >] [Last >>]

Print Reply
Subject:
From:
Steve Dirickson <[log in to unmask]>
Reply To:
Steve Dirickson <[log in to unmask]>
Date:
Wed, 26 Dec 2001 20:46:37 -0800
Content-Type:
text/plain
Parts/Attachments:
text/plain (193 lines)
> >I'm going to disagree pretty strongly with this one. Especially
since
> >I have to admit that the misconception behind this thinking is much
> >more widespread than I care for. To wit, "a good programmer puts a
> >DBCLOSE in his/her termination path, just in case the database is
> >still open."
>
> Not at all. A program, like a procedure should have a single
> exit point,

I'm aware that there are developers who adhere almost religiously to
the "one entrance, one exit" principle. I have never been one of them:
rigid enforcement of this precept seems to lead inexorably to
convoluted, deeply-nested
"if-then-if-else-butonly-except-unless-boyamiconfused" conditional
constructs that are hard to read, harder to understand, and really
easy to mess up by adding a new condition at
what-looked-like-but-wasn't-quite the right nesting level.

> at which all global-scope cleanup work is done.

I guess some developers consider closing files and databases to be
"global-scope cleanup". Except in rare cases, I am not counted among
their number.

> Scattering cleanup code
> all over the program, at every point an error is detected,
> makes for an
> unreadable program that will gain bugs as maintenance is done.

Again, closing a database when finished with it is not, at least in my
code, "cleanup code". And it is especially not "global cleanup code".

Which doesn't keep the quoted statement from being 100% wrong.
Separating the handling of error conditions from their origin is just
asking for defects: unhandled problems ("I thought Joe's magic cleanup
code would handle that"), improperly-handled conditions ("Well,
there's enough status information here to produce a meaningful error
message, but most of it got lost by the time it got to the magic
cleanup code"), and numerous other missteps ("Why should I set a
global flag for this problem? I'm not writing in BASIC!") (sorry,
Wirt).

> One of the things that MPE lacks is a supported,
> well-integrated language
> with well-integrated database handling. In the absence of
> language-mediated exception handling, the programmer must simulate
it
> with explicit transfers of control.

I'm not sure how "well-integrated database handling" and
"language-mediated exception handling" got lumped together; in my mind
they are fairly distinct issues.

> >Absolutely wrong: a *BAD* (unskilled, inexperienced, as opposed to
> >"evil") programmer does things like that, because s/he doesn't know
> >the state of the program!
>
> Half-right. A good programmer does things like that because
> s/he knows
> that it's not possible to know all possible states of a nontrivial
> program. This means that the program must be designed so that
> unexpected
> input conditions don't result in data structure damage. Placing all
> cleanup code in a single section that is executed in response to
> unexpected input conditions is a way of insuring that unanticipated
> conditions don't cause data loss.

Non sequitur; where did "unexpected input conditions" come into play?
We're talking about the failure to complete a program-controlled
operation. Though I'd contend that close-to-the-source handling of
input problems is at least as important as--probably more important
than--prompt handling of non-input-related problems, since the context
of an unexpected input tends to vanish without a trace in short order.

> >A "good" programmer knows the possible
> >states of the program at the entrance to and exit from each
> functional
> >block, and thus knows, without uncertainty, when and where a
DBCLOSE
> >is--and is not--needed.
>
> That's interesting. It implies absolute trust in the
> documentation for
> all external code, and absolute trust in the people who wrote that
> external code, and absolute trust in the people who keep the
> libraries
> updated. It implies religious reading of all manuals at every
> update to
> determine whether there are new return codes that your
> program doesn't yet know about.

Not at all; it implies competence on the part of the programmer. A
new, previously undocumented status return from a function is already
handled by good code. Depending on a number of factors (house
guidelines, the style of the developer, the tolerance level of the
user, the expected resiliency of the code, others) an unexpected
status might cause error-type termination, a warning to the user, an
entry in an exception log, or a number of other responses; in "good"
code, ignoring it is not one of the options.

> In fact, I'll go so far as to disagree absolutely: a good
> programmer is
> one who knows that s/he *cannot* know the state of the program with
> certainty at all times, and writes code in such a way as to
> insure that
> unexpected state does not propagate.

We'll have to disagree on this one. If I write something that I look
at and say "Gee, I don't really know what might be going on at this
point", I fix the defect.

> >We aren't talking about exception handling
> >here, where a "catch" block might gain control from any one of a
> >number of execution states...
>
> That's what *I'm* talking about: what is in effect a final
> "catch" block
> that will insure that certain things happen.

No, you aren't. Exception processing is, as previously mentioned,
qualitatively different from strict-sequential programming. An
exception handler is, by definition, non-sequential with any
no-exceptions-happened normal-execution-path statement, block,
function, or other unit of code. It is, however, fully specified with
respect to its possible sources, entrance points, and states.

Without exceptions, the possible paths from one statement to another
are strictly sequential, exactly specified, and invariant. Your ersatz
"final 'catch' block" is in fact a sequential entity that is reachable
from an exact, fully-specified, and invariant set of previous
sequential constructs, which are themselves reachable from an
exact.... "Please observe, ladies and gentlemen, that at no point do
my fingers leave my hands..." etc. "Magic" relies on hiding the
sequential, causative factors leading up to an event from the
perception of that event. Programming isn't magic, and the sequential
linkages aren't hidden, even when exceptions are available.

> Most recent languages
> include such a construct, but COBOL programmers have to
> construct such
> niceties for themselves. And since they have to do it
> manually, a simpler approach is better.

And the simplest way to handle unexpected conditions is to do so as
close to the point of origin as possible.

Programming with exception handling is a significantly different
paradigm than writing in strictly-sequential languages--which is why
so many newcomers to exception technology get it wrong until they
re-orient themselves. And probably why Meyers devotes over 13% of his
second "Effective" book to the subject. It is also a *much* more
expensive way to handle problems; even when exception handling is
available, it isn't usually the best way to handle predictable
readily-dealt-with abnormal situations. So don't feel bad about
COBOL's lack of the facility; the best way to handle the majority of
problems is still with prompt, informed responses from code close
enough to the problem to do something intelligent with it.

> >--although, again, "good" programmers
> >structure and partition their code such that exception processing
is
> >also built around limited, well-defined groupings of program state.
>
> Again, this is practical only when there is language support for
> exception handling.

If you'll re-read the original, you'll see that this extract is
specifically and exclusively in the "in the presence of exception
handling" clause.

> >But, whether or not exception handling is used, liberal
> sprinklings of
> >"prophylactic" FCLOSEs, DBCLOSEs, etc. at arbitrary locations
> >throughout the code are not--ever--signs of a skilled practitioner.
>
> Having exactly one DBCLOSE, placed where it will always get
executed,
> isn't exactly "liberal sprinkling".

Not having access to the code in question, I can't evaluate the
particular constructs it uses, much less make a remotely-legitimate
claim that is does "exactly one" anything, which is why I'm talking
guidelines and principles. The only specific I get from the program in
question is that it initiated a database operation that could not
possibly succeed--and then reported the failure of that operation as
an error. Pretty much everyone I've ever worked with or for called
that type of behavior a "defect". (OK, they probably called it a
"bug", but I avoid that term)

* To join/leave the list, search archives, change list settings, *
* etc., please visit http://raven.utc.edu/archives/hp3000-l.html *

ATOM RSS1 RSS2