Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

hashing external names & other goodies.

1 view
Skip to first unread message

js...@seismo.arpa

unread,
Jan 8, 1985, 10:35:25 AM1/8/85
to
The Software Tools Users' Group (STUG) long ago had available a version
of Ratfor that contained hashed longnames. This reminds me that there
are several things we can learn from the distributed authors of the
best free compiler around. When I get in to the office, I'll have to
check, but -- are break (n) and continue (n) in the ANSI Proposed
Standard yet? (If you couldn't guess, the one breaks (n) levels of
code structures -- case's, while's, etc. -- while the other continues
with the n'th enclosing loop.) Yes, I recognise the existence of
setjmp() and longjmp(), but get queasy at the thought of any kind of
jump.

Joe Yao (UUCP!seismo!hadron!jsdy / hadron!js...@seismo.ARPA)

Doug Gwyn

unread,
Jan 8, 1985, 12:00:48 PM1/8/85
to
Yuck! "break <n>;" is an accident looking for a place to happen!
If one has to have this facility, "break <label>;" is far superior.

Ron Natalie <ron>

unread,
Jan 8, 1985, 7:32:10 PM1/8/85
to
> Yuck! "break <n>;" is an accident looking for a place to happen!
> If one has to have this facility, "break <label>;" is far superior.

And "goto <label>" is even better, you don't have to change the language
at all.

-Ron

s...@mitre-bedford.arpa

unread,
Jan 9, 1985, 10:52:30 AM1/9/85
to
Ron, perhaps you missed the point. The major objection to GOTO's is that they
can lead to spaghetti code, but "break <label>" cannot do so, as it allows
only a clearly limited type of downward escape, while avoiding the pitfalls
of having to count nesting levels.

David sde@mitre-bedford

Doug Gwyn

unread,
Jan 9, 1985, 1:00:20 PM1/9/85
to
I'm sure Ron will have his own response too, but:

One can reasonably contemplate upward-compatible extensions to C.
One CANNOT seriously consider removal of heavily-used features
such as "goto". Since "goto" will be in the language anyway, it
can be used to accomplish what "break <label>" would.

I would hope that all participants in this discussion realize why
"goto" is thought ill of with respect to designing a NEW language.

Ed Nather

unread,
Jan 9, 1985, 2:11:44 PM1/9/85
to
[]

>Yuck! "break <n>;" is an accident looking for a place to happen!
>If one has to have this facility, "break <label>;" is far superior.

Or use "goto <label>" and leave C alone!

s...@mitre-bedford.arpa

unread,
Jan 9, 1985, 2:43:46 PM1/9/85
to
Please don't attribute to me something I didn't say. I was not advocating
the elimination of goto's from C, but felt the put-down of the idea of break
<label> might not have been well thought out.

Rob Warnock

unread,
Jan 9, 1985, 5:06:43 PM1/9/85
to
+---------------

| Yuck! "break <n>;" is an accident looking for a place to happen!
| If one has to have this facility, "break <label>;" is far superior.
+---------------

I second the motion. The BLISS-10 language (which has no explicit "goto")
originally had "EXITWHILE" and "EXITCASE" and "EXITBLOCK" and... so they
added a simple "EXIT n". Well, after a while they got tired of the hassle
and replaced all that with labelled blocks so you can "LEAVE label".
In pseudo-C:

foo:{ ...
... break foo;
...
}

If one were to add this to "C" I would suggest somehow managing to force
a label onto the END of the block which matches the one at the beginning,
so that it is easy to scan forward and see where the block ends.

But note that "C" already HAS this construct, if one doesn't mind some
disciplined use of "goto". (I have seen this style already in some code.)
Simply put the label just INSIDE the END of the block:

#define leave goto /* preferably deep in a header file */

...
{ /*BLOCK foo*/
...
... leave foo;
...
foo:}
...

The point of using "leave" rather than "goto" is to emphasize that one
is using a hierarchical control flow, and not jumping all over the place.
Again, the disclipline of labeling the block entry is very important, as
otherwise the reader hits the "leave foo" without knowing he/she is IN "foo"!

(Any flamers about "goto" should recognize first that "return" is in fact
just such a structured forward "goto". Dijkstra's paper was about the
UNRESTRICTED use of "goto", not the existence of it at all.)

Whether or not you have it in the compiler is not particularly important as
far as code generation -- a decent data-flow/control-flow analyzer can easily
deal with such forward-and-out "goto"s -- nor to ENFORCE the discipline
(since as long as "C" has the unrestricted "goto" one must hope the programmer
does not write spagetti code), but simply so that the compiler could check
that the brackets and labels match (no use of "leave label" if we're not
in a block named "label").

So finally, perhaps we should simply extend "lint" to warn of any "goto"
whose target is not just inside the end of an enclosing block, and leave
the poor compiler alone! (One could even get "lint" to check that the
block started with a "/*BLOCK foo*/" comment!)


Rob Warnock
Systems Architecture Consultant

UUCP: {ihnp4,ucbvax!dual}!fortune!redwood!rpw3
DDD: (415)572-2607
USPS: 510 Trinidad Lane, Foster City, CA 94404

Guy Harris

unread,
Jan 9, 1985, 6:22:58 PM1/9/85
to
> Please don't attribute to me something I didn't say. I was not advocating
> the elimination of goto's from C, but felt the put-down of the idea of break
> <label> might not have been well thought out.

But what Ron was saying was that if you don't eliminate "goto", "break <label>"
just amounts to "semantic sugar" for "goto <label>"; if you want to discourage
people from using "goto" you can just put

#define breakloop goto

or something like it in a header file. Putting in a "break" statement which
acts exactly like "goto" but which is only accepted by the compiler in certain
contexts doesn't really add anything to the power of the language.

Guy Harris
{seismo,ihnp4,allegra}!rlgvax!guy

Spencer W. Thomas

unread,
Jan 9, 1985, 10:14:30 PM1/9/85
to
This topic was extensively hacked over in this list only 2 or 3 months
ago. Are peoples memories _ r_ e_ a_ l_ l_ y that short????

Please desist.

--
=Spencer
({ihnp4,decvax}!utah-cs!thomas, tho...@utah-cs.ARPA)
<<< Silly quote of the week >>>

Mark Terribile

unread,
Jan 10, 1985, 1:15:29 PM1/10/85
to
> -- are break (n) and continue (n) in the ANSI Proposed Standard yet? (If
> you couldn't guess, the one breaks (n) levels of code structures -- case's,
> while's, etc. -- while the other continues with the n'th enclosing loop.)
> Yes, I recognise the existence of setjmp() and longjmp(), but get queasy at
> the thought of any kind of jump.

I hope these NEVER get in! This is a great way to write fragile code, and
there is a MUCH more durable way to get what you are trying to get

Why is it fragile? Well, it's easy to break it accidentally when
you rework code.

while( ... )
switch( ... )
{
case ..:
... lots of code ...
break 2;
... lots more code ...

break;
case ..:
...
}

What happens when that ``lots of ... lots more code'' gets surrounded by
another loop or another switch in the course of the program's evolution?

This is a great pitfall for ``the next guy'' who is going to use this code.
This design is only pleasing to sociopaths.

One better way is with (horrors) a label. Both ADA and (extended) PL/I
do this, and it seems to work pretty well. The exact forms differ from
language to language, but in C it might take the form of


while( ... )
command_char:
switch( ... )
{
case ..:
... lots of code ...
break command_char;
... lots more code ...

break;
case ..:
...
}

This is now solidly immune to the addition of new levels of control between
the structure to be ``broken'' and the decision to break it.
--

from Mole End Mark Terribile
(scrape .. dig ) hou4b!mat
,.. .,, ,,, ..,***_*.

Ron Natalie <ron>

unread,
Jan 10, 1985, 3:43:37 PM1/10/85
to

> |And "goto <label>" is even better, you don't have to change the language
> |at all.
> |
> |-Ron
>
> Ron, perhaps you missed the point. The major objection to GOTO's is that they
> can lead to spaghetti code, but "break <label>" cannot do so, as it allows
> only a clearly limited type of downward escape, while avoiding the pitfalls
> of having to count nesting levels.
>
> David sde@mitre-bedford

I do understand the point, but BREAK-TO is not structred anymore than
any sort of gotos. If you just say, it's OK to user goto's rather only
in these well-defined casees, you can get by WITHOUT MAKING GRATUITOUS
AND UNNECESSARY CHANGES TO THE LANGUAGE. BREAK-TO is a total unnecessary
change. You're not going to be able to get rid of goto (one of the nice
things about C is that it allows careful programmers to break the structure
and typing rules), adding break-to is redundant.

-Ron

Mike Lutz

unread,
Jan 10, 1985, 5:56:27 PM1/10/85
to
> ... Putting in a "break" statement which

> acts exactly like "goto" but which is only accepted by the compiler in certain
> contexts doesn't really add anything to the power of the language.
>
> Guy Harris

I disagree with Guy on this one (exceedingly dangerous, if you know
what I mean, and I think you do :-). If indeed the break <label> is
added so that a) the <label> must be associated with a control construct in
which the break is nested and b) causes execution to start with the
first statement following this construct, then indeed it is different
from (and, I argue, a useful alternative to) goto <label>. Guy is
right - break <label> does not extend the power of the language; if
anything, it limits it (or, better yet, controls it).

The altered semantics *are* important. Sure, the documentation effects
can be achieved by strict adherence to programming conventions and the
use of a #define like the one Guy proposed. However, the error
detection possibilities are every bit as important (I vaguely remember
making an error long ago), and the limited form of goto can turn
difficult to diagnose run-time errors into compile-time errors.

All of this ignores, of course, any assessment of the problems of
incorporating this facility in C relative to its worth. I've no
illusions about the difficulty, especially when you realize that all
labels are potential targets of a goto but some are also possible
referents of the new break. But I was addressing the absolute utility
of the construct, rather than its relative utility when considering
the engineering problems of such a retrofit.
--
Mike Lutz Rochester Institute of Technology, Rochester NY
UUCP: {allegra,seismo}!rochester!ritcv!mjl
CSNET: mjl%r...@csnet-relay.ARPA

Martin Minow

unread,
Jan 10, 1985, 6:40:10 PM1/10/85
to
break <label> failed to win widespread acceptance because
people couldn't agree where the label goes (anywhere, or
should it label the "proper" enclosing block, or what.

Goto, as noted, gives the necessary piece of information
and can serve as a visible warning that something special
is going on.

While scanning the source of a module done by one of
my collegues, I noticed a label at the start of a module.
"Why did you need a goto here?"

His reply was that he uses

label: ...
goto label;

to delimit an outer loop that goes on for several pages as
you can easily lose visual track of {...} nesting levels.

The moral is that goto is a perfectly valid addition to
a programmer's toolkit and that squeezing the last goto
out of a module may make it less maintainable even though
it improves the module's "structuredness".

Martin Minow
decvax!minow

Thomas Murphy

unread,
Jan 10, 1985, 7:10:02 PM1/10/85
to

By this reasoning we can quickly reduce ourselves to working with a turing
machine. A while statement is redundant because we have goto and if
statements. "break <label>" reflects a structured concept that mirrors how I
view a problem being solved; besides it is not as random and clumsy as a goto.

Tom murphy@lll-tis

Doug Gwyn

unread,
Jan 11, 1985, 3:22:36 AM1/11/85
to
I really think the discussion of "goto" in C is overblown.
I just grepped through over 6,000 lines of production C code
and found one instance of goto used as an EOF exception escape
and 7 instances (in the same module) of gotos to a common error
return. Not a single goto for any other purpose, including
multi-level breaks. I would argue that this code exhibits
why "goto" can be useful and that the "dangerous" uses of it
can be totally avoided. Perhaps programmer education is more
important than changing the language.

Tracy Tims

unread,
Jan 11, 1985, 10:47:57 AM1/11/85
to

In "break <label>;" the label is used to identify the control structure being
exited, rather than the place being exited to. It is more robust in terms of
future program changes, and it has the advantage of being defined only in terms
of structured constructs.

loop1: while ( <cond1> ) {
.
.
while ( <cond2> ) {
.
break loop1;
.
}
.
.
}

Tracy Tims {linus,allegra,decvax}!watmath!...
Human Computing Resources Corporation {ihnp4,utzoo}!...
Toronto, Ontario, Canada. 416 922-1937 ...hcr!hcrvx1!tracy

Mark Terribile

unread,
Jan 11, 1985, 1:14:53 PM1/11/85
to
>But what Ron was saying was that if you don't eliminate "goto",
>"break <label>" >just amounts to "semantic sugar" for "goto <label>";
>if you want to discourage people from using "goto" you can just . . .

Not quite. You see, if you follow out this philosophy, we can do away with
for(;;) and while() and the else in if()-else ... and compound statements
too.

An upholsterer's tack hammer is no more powerful than a 15-lb maul. Why use
the tack hammer? Because it is suited to the job. More specifically, it lets
you put the force you need where you need it without scattering that force
everywhere else.

The labelled break allow you to get out of (i.e. go to just below) a loop
without making it possible to get there from anywhere else. Very important.

Viewed differently, the labelled break is the addition of a (presumably) needed
capability to the thing that needs it (the loop and switch statements)
without making the remainder of the program unsafe.

MLY.G.SHA...@mit-mc.arpa

unread,
Jan 12, 1985, 1:08:31 AM1/12/85
to
> Perhaps programmer education is more important than changing the language.

at last somebody who understands. it's the programmer who writes the
damn code not the language compiler.

shades@mit-oz

Guy Harris

unread,
Jan 12, 1985, 1:49:15 AM1/12/85
to
> By this reasoning we can quickly reduce ourselves to working with a turing
> machine. A while statement is redundant because we have goto and if
> statements. "break <label>" reflects a structured concept that mirrors how I
> view a problem being solved; besides it is not as random and clumsy as a goto.

The difference is that writing a "while" loop using "if" and "goto" yields
clumsy and harder-to-read code; replacing the word "break" with the word
"goto" merely makes the program "goto"-less. A "break" (or a "continue") is
a fairly arbitrary transfer of control; "goto" is, admittedly, more arbitrary,
but all of them require you to read a bit to discover where control is
actually going.

for (<something) {
while (<something else>) {
.
.
.
break foobar;
}
}
foobar:

is no less clumsy than

for (<something) {
while (<something else>) {
.
.
.
goto foobar;
}
}
foobar:

The only possible merit of labelled "break" and "continue" is that they
can't be misused in the ways that "goto" can. There are many ways of
writing poor code, and since we can't make "goto" go away in C we're stuck
with that particular way. We'll have to rely on education to prevent
spaghetti code. (There are instances where using "goto"s to cause two
separate paths through code to join at common code is *more* readable, say,
than duplicating the code. Admittedly, in the one recent instance I've
written of this sort, the whole thing should be done using a different
technique of joining those paths, but that's competing with several other
items on my TODO list.)

Guy Harris
{seismo,ihnp4,allegra}!rlgvax!guy

Doug Gwyn

unread,
Jan 12, 1985, 2:54:17 PM1/12/85
to
People keep hoping for the magic panacea that will ensure automatic
correctness of their programs. Last year it was Ada; this year it
is knowledge-based program writing systems; next year it will
be something else. I keep seeing the same ideas attempted over and
over as the years go by. The one idea that works, to think clearly
and carefully, has not found much favor.

Tim Smith

unread,
Jan 12, 1985, 3:55:54 PM1/12/85
to
Turnh on :-) mode.

In the two methods for breaking loops:

/* /*
* Method A * Method B
*/ */
loop: while ( foo ) while ( foo )
{ {
. .
. .
break loop; goto endloop;
. .
} }
endloop:;

many people seem to prefer A, because the label is at the start of the
loop, rather than at the end of the loop.

It seems to me that the obvious thing to do is to change the goto statement.
Goto should have the form

goto label [ {+,-} constant_expression ] ;

The constant expression tells how many statements away from the label
to 'goto'. For example, the while loop break would be written like this:

/*
* Method C
*/
loop: while ( foo )
{
.
.
goto loop + 1;
.
}

Exit :-) mode

How are 'do' loops to fit in with 'break label'?
Does the 'label' go with the 'do' or the 'while'?
--
Duty Now for the Future
Tim Smith
ihnp4!wlbr!callan!tim or ihnp4!cithep!tim

Guy Harris

unread,
Jan 12, 1985, 6:58:12 PM1/12/85
to
> Not quite. You see, if you follow out this philosophy, we can do away with
> for(;;) and while() and the else in if()-else ... and compound statements
> too.

Yes, but

while (<condition>) {
...
}

is easier to read and write than

loop:
if (!<condition>)
goto endofloop;
...
goto loop;

while one "ed" command, or one #define, can turn

while (<condition>) {
...
breakloop label;
...
}

label:

into its "goto" equivalent. (Putting the label at the beginning of the
loop would make that harder, but it would also make it harder for the reader
to find the point that the "breakloop" goes to.

> The labelled break allow you to get out of (i.e. go to just below) a loop
> without making it possible to get there from anywhere else.

Except for one problem: nobody's proposed deleting "goto" from the C language
(and anybody who proposes it should personally have to rewrite every program
that uses it safely). As such, C *will* let you get anywhere from anywhere
else (within a function body, at least) even with the addition of the "break
<label>" construct.

If we're designing a *new* language, we might consider fancier "break"
statements and no "goto" (although even "break" and "continue" can impair
the readability of a program). Since C already has a "goto", though, and
it's impractical to eliminate it, I don't think "break <label>":

1) makes the language easier to write in
2) makes it easier to read programs
3) makes it easier to verify programs
4) makes it easier to optimize programs

I presume that any flowgraph that for a program written with "safe" "goto"s
can be rewritten either with "break <label>" and "continue <label>", or by
node splitting (i.e., where "goto" is used as a way of folding code). This
is probably close to a formal statement of my notion of "safe" "goto"s, and
probably close to most other people's notion as well. If so, you can
formally eliminate "goto"s from programs, so the only question that comes up
is whether the informal aspects of readability and writability are affected
by the addition of "break <label>". I don't think it's affected enough
to make it worth the trouble of adding "break <label>" to the language. As
I've said, even unlabelled "break" and "continue" statements can impair
readability; it's harder to find the end of a loop when examining its innards
in detail than when looking at the loop as a whole, so that it is less obvious
what the flow of control is when looking at the "break" in

while (<condition>) {
...
if (<condition 2>)
break;
...
}

then when looking at the "while" loop as a whole. (I.e., it's more obvious
that control flows from the code before the closing "}" to the condition
test on the "while" line than it is that control flows from the "break"
statement to the code after the closing "}".) I would still use a "break"
in this case, out of habit and out of a partially-superstitious desire to
avoid a "goto", even though putting in a label might make it easier to
see where the "goto" goes to; also because it means I don't have to invent
a name for the label. Putting in a "break <label>", however, means I have
to invent a label. And if the label goes at the beginning of the loop,
rather than the end, you have to search for the label and then search for
the end of the loop to figure out where it goes. This is becoming a
problem in the psychology of programming; does anybody have any hard evidence
for or against the proposition that labelled breaks - of either kind - make
it easier to program? If not, we're all trading anecdotal evidence, and
the horse's corpse is beginning to look a bit messy...

Guy Harris
{seismo,ihnp4,allegra}!rlgvax!guy

Henry Spencer

unread,
Jan 12, 1985, 8:07:35 PM1/12/85
to
> While scanning the source of a module done by one of
> my collegues, I noticed a label at the start of a module.
> "Why did you need a goto here?"
>
> His reply was that he uses
>
> label: ...
> goto label;
>
> to delimit an outer loop that goes on for several pages as
> you can easily lose visual track of {...} nesting levels.

The right comment on this is "why don't you split that loop body
up into separate functions, as God clearly intended?" :-). If it's
long enough to make tracking indenting levels difficult, it's too
long to be in one monolithic piece.
--
Henry Spencer @ U of Toronto Zoology
{allegra,ihnp4,linus,decvax}!utzoo!henry

Tony Li

unread,
Jan 12, 1985, 10:18:48 PM1/12/85
to

From: Doug Gwyn (VLD/VMB) <gwyn at BRL-VLD.ARPA>

It has not found much favor because it does not work well. Consider
the lifecycle of an average software package. Currently, for *ANY*
software package, you should expect to spend at least half of your
budget on maintenance.

The hope is that the development of a automatic correct program
generator would help to eliminate much of this maintenance cost.

Cheers,
Tony ;-)

MLY.G.SHA...@mit-mc.arpa

unread,
Jan 13, 1985, 10:00:56 AM1/13/85
to

agreed that a significant amount of all software production is
spent doing simple maintenance i still agree with doug gwyn that clear
thinking (i.e. good old common sense) would improve correctness,
maintainability, and reduce cost more than compiler enforced rules.
something that i have noticed out in the "real" world is that
the more complex the language rules, no matter how rigidly enforced,
the more drastic the increase in the time necessary for the 'average'
(six month matchbook cover) programmer to produce even the simplest of
programs (unfortunately these are also the ones least likely to use
their common sense). it cuts both ways. rigidity and higher costs in
development or looseness and higher maintenance costs.
one major problem that i commonly see is that the more junior
the programmer the more likely he/she/it will be doing the
maintenance. this is a serious problem. the person with the least(!)
experience is given the job where that person can do the most damage.
(sigh)

anyway when it gets down to brass tacks my objection to break
label is mainly on the grounds that enforcing the construct properly
would be adding a grievous burden upon the compiler. if the label is
placed before the block that it escapes the compiler must generate two
internal labels for that label, one for the break and one for a
possible goto. this is of course only a hazard on smaller machines
supporting small symbol tables but it still is an unecessary

B. Banerjee

unread,
Jan 13, 1985, 3:05:03 PM1/13/85
to

Yo folks! Howzabout

# define break_to goto
.
.
break_to <label>

Voila! you have your semantic sugar, whilst the rest of us recalcitrant
types can use 'goto' to break multi-level loops, WITHOUT changing the
language. What is that you say? You like labelling your loops at the
top? Sorry! Ever hear of backward goto's, and how confusing they are?
The natural process of reading (code or otherwise) happens to be forward.

--
Binayak Banerjee
{allegra | astrovax | bpa | burdvax}!sjuvax!bbanerje
P.S.
Send Flames, I love mail.

Tony Li

unread,
Jan 13, 1985, 6:45:02 PM1/13/85
to

Whoa! I'm not out to automate current design practices. I'm much
more interested in providing a NEW design methodology whereby the
compiler (or some other entity - like lint for C) goes through and
either (1) proves your program correct or (2) derives a provably
correct program from a proof of an algorimth.

Work is currently being done on both these topics on a very small
scale, and things look quite promising except for the fact that doing
these things take mega-cycles. Once we know enough to where we could
make things efficient, this should greatly simplify the software
design process. Ultimately, it might be possible to have the designer
just state the goals, and let the system generate all of the code,
e.g. "Sort these numbers, and write them to tape as an ANSI file
FOO.BAR".

The heuristics are involved when we try to generate "good" code for a
specification that has a little leeway. Since there are lots of
possible implementations, and we don't have the opportunity to look at
all of them, we need a heuristic to help decide the implementation.

So actually, I guess that I'm in favor of giving the programmer a lot
of assistance in 'thinking logically and clearly'. Currently, this is
a tough proposition, and is done by a very few people. I'm hoping
that this would mean that new programmers would have to learn very few
new rules (mostly Boolean logic - that's not unreasonable, is it? ;-).
And with that, you could dispose of a lot of nitpicking rules that we
have now.

[End of digression, back to reality]

As to break <label>, I have mixed feelings. Yes, it's a cleaner
feature than a goto. Unfortunately it's not trivial to implement, and
it's a new feature, which means that it would wind up in C from now to
eternity, along with 'goto'. I'm not sure that the gain makes up for
the burden on the language design.

Cheers,
Tony ;-)

ross m. greenberg

unread,
Jan 14, 1985, 8:59:00 AM1/14/85
to
he...@utzoo.UUCP=>

> If it's
> long enough to make tracking indenting levels difficult, it's too
> long to be in one monolithic piece.

I disagree. If the piece of code is time critical or used ALOT, then
the extra calls to subroutines might become too much overhead. There was
a piece of code I had the misery to maintain a while back that had only
about TWELVE levels of nesting. Try as I could I couldn't break it out
into more efficient code, just easier to look at code. The ratio of
ridiculous nesting level time to fun-to-look-at code was somewhere about
1.6:1, and I couldn't afford the extra time as this was a psuedo-realtime
job.

Of course, I did change tabbing to just a few spaces, so I didn't have
to use two tubes :-)


------------------------------------------------------
Ross M. Greenberg @ NYU ----> { allegra,ihnp4 }!cmcl2!acf4!greenber <----

Rob Warnock

unread,
Jan 15, 1985, 12:04:54 AM1/15/85
to
+---------------

| People keep hoping for the magic panacea that will ensure automatic
| correctness of their programs...
+---------------

Quite so, Doug. Also see the current? issue of "Whole Earth Review",
on the theme of "Computer As Panacea: All Panaceas Turn To Poison".

+---------------
| ... The one idea that works, to think clearly


| and carefully, has not found much favor.

+---------------

There is a reason. It is painful to do so until one has been trained
(disciplined) enough so that the results of NOT doing so are more
painful than the thinking. The training takes a long time. It too
is painful. There are not many teachers/mentors/gurus/old-timers
around who can help us through the rough stages, and doing so on
one's own is not likely (though possible). The sage advice printed
in books pales against your bosses' demands for "More!" and "Now!".
It requires an exceptionally hospitable environment (such as being a
support staff member in a graduate or post-graduate research atmosphere).

I remember the first time I seriously tried to write a program that would
be "perfect", that is, to compile and execute correctly the first time
it was submitted to the system. (I had gotten all excited reading Djikstra
or somebody, and had this wild hair about "zero defect" programming.) I was
just switching from MACRO-10 (the assembler) to BLISS-10 (which has no "goto")
for doing systems programming, and was writing a "stdio"-like I/O package.
(BLISS-36 now comes with "EZIO", but it didn't exist then.) The specification
was fairly simple. I wanted the program:

MODULE TEST =
BEGIN
REQUIRE IOX.REQ; ! These days we say "#include <stdio>"

LOCAL C;

WHILE (C = GETC()) NEQ IOX_EOF
DO PUTC(.C);

END
ELUDOM

to give the user a standard prompt (using SCAN/WILD, for you TOPS-10 folk),
accept a command string of

*OFILE=IFILE1,IFILE2,...

and do "sort of the same as" the UNIX command "cat ifile1 ifile2 ... >ofile".

The exercise in fact succeeded, but it was *P*A*I*N*F*U*L*. (And I don't
just mean giving up the "goto"!) The only way I managed to do it was to
write the entire program on paper, in a notebook, saving all versions and
notes and scratchings, and REWRITING each module in a clean form for each
step of refinement or backup. (Yes, I had to back up a lot.) A couple of
times I started typing it in, but realized there were pieces missing, and
went back to the notebook. That was possibly the most painful part -- staying
away from the machine. But it paid off. When finally typed in (and printed
out BEFORE compiling and desk-checked and corrected), it compiled and ran.

I am sorry to say that many times in the years since I have allowed myself
to become seduced again by the very addictive nature of working "on line",
sometimes to the extent that I could not consider working if the computer
was "down" (even when what I had to do could be done on paper!). But sometimes
when the project was just too big for me to hold in my head or on the 25 lines
of the screen, or when I just HAD to get it done right and on time, I would
revert to the "primitive" methods of pencil and paper, of "design before code".

I feel I have learned several lessons:

#1: "Zero defect" development of software is possible, but it requires
a severe discipline in how one works.

#2: Even for people who know #1, and who understand what it implies, it is
never easy. Constant little temptations or pressures arise to try to
shortcut the necessary steps. It never gets any easier. The whole
environment must support the effort.

#3: Knowing #2, the only way we will do it is if we realize the cost of NOT
doing it (bugs we'll never find, slipped schedules, cost overruns, and
maintenance headaches).

#4: Most software development organizations ("Management") are not willing
to face #3 (see any book on Quality Control), so since #2 is still true,
"zero defects" becomes impossible, or at least unlikely. Even individuals
who understand #1, #2, and #3 find difficulty in consistently applying
their understanding on problems that seem "too small" or "not worth it"
(i.e., we ignore the cost to ourselves in getting sloppy in our discipline).

#5: Both large organizations and individuals tend to severely underestimate
the scope of tasks, thus reinforcing #4.

How does this concern net.lang.c? In my experience, C is "good enough"
as it is. The above considerations far outweigh the minor wrinkles the
net has seen discussed recently (e.g. how to initailize unions, "goto"
versus "break" versus "leave"). Yes, C can be tuned a bit, and people
would benefit from it, I suppose.

(I favor the "leave <labelled-block>", myself, but frankly I don't recall
having ever used a "goto" in C, for ANY purpose, so who am I to say?)

But to some extent, such discussions of the effect of programming constructs
on program correctness are similar to discussing the effect of the color of
automobile dash panel indicators on traffic safety while driving 90 miles
an hour in the rain, with one hand on the wheel, drinking whiskey, with the
radio turned up to deafening, your headlights off, and no seatbelt.

(While the sarcasm of the previous sentence may be a bit heavy, consider
the New England pediatrician who completely gave up his medical practice
of many years and went to work lobbying for infant car seats. He had looked
up one day and discovered that preventible auto-accident injury killed more
of his young patients than ALL other causes COMBINED, including disease and
all non-auto accidents.)

+---------------
| ... The one idea that works, to think clearly


| and carefully, has not found much favor.

+---------------

Frank Adrian

unread,
Jan 15, 1985, 10:44:49 AM1/15/85
to
In article <49...@utzoo.UUCP> he...@utzoo.UUCP (Henry Spencer) writes:
>> While scanning the source of a module done by one of
>> my collegues, I noticed a label at the start of a module.
>> "Why did you need a goto here?"
>>
>> His reply was that he uses
>>
>> label: ...
>> goto label;
>>
>> to delimit an outer loop that goes on for several pages as
>> you can easily lose visual track of {...} nesting levels.
>
>The right comment on this is "why don't you split that loop body
>up into separate functions, as God clearly intended?" :-). If it's
>long enough to make tracking indenting levels difficult, it's too
>long to be in one monolithic piece.
>--
Unfortunately, Henry, things aren't always that simple. If one is
dealing with time critical or often used code within a loop, the
overhead inccurred with all of the procedure calls can add up.
I once shaved 30% execution time off a program by expanding a routine
call in an often traversed loop. Funny, it didn't seem to make the
program more readable. Well, I guess that's the breaks. The point
is that sometimes execution speeds are critical and "good" coding
style gets in the way of speed. That is unless you find me a C
compiler which automatically does inline routine expansion. Now
if you would have suggested using macros...
"Rules are made to be broken..."
Frank Adrian

Henry Spencer

unread,
Jan 15, 1985, 1:30:45 PM1/15/85
to
> People keep hoping for the magic panacea that will ensure automatic
> correctness of their programs. Last year it was Ada; this year it
> is knowledge-based program writing systems; next year it will
> be something else. I keep seeing the same ideas attempted over and
> over as the years go by. The one idea that works, to think clearly
> and carefully, has not found much favor.
>
> It has not found much favor because it does not work well. Consider
> the lifecycle of an average software package. Currently, for *ANY*
> software package, you should expect to spend at least half of your
> budget on maintenance.

I fail to see how this contradicts anything Doug said. Unless, of
course, you add an implicit "...and your maintenance programmers will
be dolts, incapable of clear and careful thought"!

Ron Natalie <ron>

unread,
Jan 15, 1985, 3:23:32 PM1/15/85
to
> All of this ignores, of course, any assessment of the problems of
> incorporating this facility in C relative to its worth. I've no
> illusions about the difficulty, especially when you realize that all
> labels are potential targets of a goto but some are also possible
> referents of the new break. But I was addressing the absolute utility
> of the construct, rather than its relative utility when considering
> the engineering problems of such a retrofit.
> --
Agreed. I'm not saying break-to-label isn't a good thing for some language
to have. There's a lot of things we could put into languages if we were
starting over. What I'm arguing against is making frivolous changes to an
existing language. So far nearly all of the proposed extensions that the
committe has been proposing, do not change the language when it can be
avoided.

If we trully want to be structured we'd get rid of "break" and "goto"

-Ron

Ron Natalie <ron>

unread,
Jan 15, 1985, 3:29:14 PM1/15/85
to

Yes, this is an indication that the reason most good programmers
place non-structured constructs in their code is to avoid code
duplication.

-Ron

Doug Gwyn <gwyn>

unread,
Jan 15, 1985, 5:27:43 PM1/15/85
to
> ... this is an indication that the reason most good programmers

> place non-structured constructs in their code is to avoid code
> duplication.

Or to handle errors and exceptions that cannot be reasonably
treated by the main program logic. The alternative often is
to ignore these, with loss of robustness, or to carry around
lots of silly state flags to be tested in loop conditions.

Dick Dunn

unread,
Jan 17, 1985, 1:11:58 AM1/17/85
to
> Whoa! I'm not out to automate current design practices. I'm much
> more interested in providing a NEW design methodology whereby the
> compiler (or some other entity - like lint for C) goes through and
> either (1) proves your program correct or (2) derives a provably
> correct program from a proof of an algorimth.
>
> Work is currently being done on both these topics on a very small
> scale, and things look quite promising except for the fact that doing
> these things take mega-cycles...

I'm not impressed by any argument based on program proof, for the simple
reason that the essence of the above statement--"we want to prove programs,
we think we can do it and we've done something with small programs; all we
have to do is scale it"--has been true for AT LEAST ten years.

A brief, lucid discussion of the scaling problem can be found in "Notes on
Structured Programming", Dijkstra, in the book _Structured_Programming_ by
Dahl, Dijkstra, and Hoare.
--
Dick Dunn {hao,ucbvax,allegra}!nbires!rcd (303)444-5710 x3086
...A friend of the devil is a friend of mine.

Guy Harris

unread,
Jan 18, 1985, 12:12:16 AM1/18/85
to
> The point is that sometimes execution speeds are critical and "good" coding
> style gets in the way of speed. That is unless you find me a C
> compiler which automatically does inline routine expansion.

According to the C++ Reference Manual, the C++ compiler does do exactly that.
It's a good idea, but the only other compiler I know about which does it
is Xerox's Mesa compiler (I suspect there are others.)

Guy Harris
{seismo,ihnp4,allegra}!rlgvax!guy

Henry Spencer

unread,
Jan 18, 1985, 5:14:20 PM1/18/85
to
> Unfortunately, Henry, things aren't always that simple. If one is
> dealing with time critical or often used code within a loop, the
> overhead inccurred with all of the procedure calls can add up.
> I once shaved 30% execution time off a program by expanding a routine
> call in an often traversed loop. ... The point

> is that sometimes execution speeds are critical and "good" coding
> style gets in the way of speed. ...

Agreed, unfortunately. But pragmatic perversions that are necessary
about 0.1% of the time should not be held up for public acclaim as
examples of recommended style.

Rob Warnock

unread,
Jan 18, 1985, 5:54:08 PM1/18/85
to
+---------------

| How are 'do' loops to fit in with 'break label'?
| Does the 'label' go with the 'do' or the 'while'?
| Tim Smith | ihnp4!wlbr!callan!tim or ihnp4!cithep!tim
+---------------

The label goes with the "do", since it is a "do" statement. "Break <label>"
says: "Go to just outside the labelled statement". (See K & R for "statement".)

Keep in mind, that any "break <label>" should also (for orthogonality) work
on a "compound statement", not just on loops. The semantics are the same. The
normal "continue" construct can be thought of as a "break <label>" for which
the labelled statement is the loop BODY, not the loop itself.

while (...){ while (...) zork:{
... ...
if (...) continue; if (...) break zork;
... ...
} }

The application to multi-level loops is straightforward.

p.s. If we're going to change the language, I vote for the generic
"leave <label>" of any labelled statement (a. la. BLISS), rather than
twisting the meanings of the current "break" and "continue".

lmi...@ucla-cs.uucp

unread,
Feb 3, 1985, 4:25:38 PM2/3/85
to

This is about working away from the terminal, and zero defect programming:
There was a fascinating paper 10 years ago by Seven, Boehm and Waton,
"The Lockout Effect" that compared time and quality of solution of a
mini programming exercise given to experienced programmers for various
amounts of time away from the terminal, from unlimited use to being
locked out for up to 1/2 hour after each job submission. Those with
the longer longout times performed better.

The authors did not go into much discussion of the reasons for the
effect, but it is worth thinking about.

0 new messages