Re: COBOL ain't quite dead - yet !



Richard wrote:

As I have already said, when examining a program to determine the flow
of control there is nothing wrong with goto. It is perfectly clear
what will happen at that point.

The problem is entirely that when looking at the code and there is a
label then, in a program that has gotos, it is not possible to know
the flow of control around that label without examining the whole
program for references to that label, and to the one above, and the
one above that.

I think it's worse than that. I believe the goto statement itself can
obscure the flow of control, in a number of plausible cases, even
though the operation of the goto is perfectly clear.

The problem, again, is that it interferes with abstraction.

Consider a loop that iterates over a list or array of numbers, adding
1 to each value.

The highest-level abstraction I can think of, off the top of my head,
is successive function application, as with the map and fold
operations typically provided by functional languages. You simply
write the equivalent of "do this to everything in the list". In LISP,
for example:

[assume a function "add1" that adds 1 to a number]
(mapcar 'add1 list)

will add 1 to every value in list. The loop is entirely abstracted away.

The second-highest is an automatic container iterator like the foreach
operator provided by some languages:

foreach item in list
do
add 1 to item
done

Here the loop is explicit, but the invariant is implicit in the
syntax. A maintainer looking at a foreach statement knows the intent:
there's some body that will be applied to every object in the collection.

Then we have well-formed loops with a single invariant and a looping
control structure. For example, in C:

while (*item) *item++ += 1;

and at roughly the same level of abstraction, index-incrementing loops:

[initialize "count" to number of items in list]
perform varying idx from 1 by 1 until idx > count
add 1 to list(idx)
end-perform

Here the loop is explicit, and the invariant is explicit; but at least
the invariant is simple, and the mechanism by which it changes is
simple, and we're using a standard idiom that a maintainer can easily
recognize.

Goto statements, however, don't imply a loop; there are forward gotos,
and backward gotos that shouldn't cause a return to the goto
statement. And they say nothing about the invariant; instead, they
have to be wrapped in a branch. All of that decreases the level of
abstraction, and forces a human reading the source to look at more
context in order to discern control flow.

Here's an example:

[initialize "count" to number of items in list]
move 1 to idx
loop-for-list.
if idx not > count
add 1 to item(idx)
add 1 to idx
go to loop-for-list
end-if

The loop invariant is still pretty clear, but it's not obvious from
the syntax that it *is* the loop invariant. And it's modified several
lines later. And the go to and its target aren't clearly associated by
the syntax.

What was a one-word or one-line control structure has become several
lines, spread across the loop body.

And that's the best case. More often, a goto-based loop will have its
invariant test, invariant modification(s), and branching in various
places, with no obvious connections. So the maintainer has to keep
track of all of them to ferret out the control structure.

Gotos pose similar problems to software-processing programs, such as
optimizers. A foreach loop does one thing, which makes it easy to
optimize. Often the entire loop body is a single basic block. Gotos,
on the other hand, are general-purpose; they don't provide clues for
the optimizer. And they fragment the basic blocks, which reduces
opportunities for peephole and flow optimization.

--
Michael Wojcik
Micro Focus
Rhetoric & Writing, Michigan State University
.



Relevant Pages

  • Re: GOTO and Bourne shell
    ... > You have a loop in some comms software. ... that would be another form of control coupling. ... An FSM has states, ... effect as if you used a goto. ...
    (comp.unix.shell)
  • Re: GOTO and Bourne shell
    ... You have a loop in some comms software. ... definitely do within the body of the loop, and exit the loop with a goto ... > main control loop evaluate the combination of current conditions to ... in an FSM as such. ...
    (comp.unix.shell)
  • Re: address of a statement in C
    ... >> of a loop. ... When programming you are *always* in the scope of some invariant or ... > true of the latter two as it is of goto stands. ...
    (comp.lang.c)
  • Re: address of a statement in C
    ... except for breaking from a switch - violates the loop invariant. ... goto doesn't mess *mine* up. ... And I claim that your explanation and "'proper' usage" are bogus. ...
    (comp.lang.c)
  • Re: Using On Error to Exit Loop...ok?
    ... use "On Error GoTo.." ... as a way to exit a loop? ... You can use this code to find the lowest unused Index value for your PictureBox1 control array without resorting to error trapping... ...
    (microsoft.public.vb.general.discussion)

Loading