I guess it depends on how you think of it.  I don't think of it the way it is 
stated that people think of it.  I think of it as "read each record in a file, 
processing each one."  Neither of those loops TRULY represent this


I think this is one reason why many languages go with the "for each" paradigm, 
with the details of reading the record and processing or terminating really 
hidden from the end user.  For example, in pseudo-code


foreach my-record in my-file

do

   [...]

end


the "foreach" process will read each record in my-file and invoke the code in 
the do...end block for each one.  Upon reaching the EOF condition it will 
return out of the foreach process.


The actual code behind this "foreach" could be either of the two methods below, 
but it doesn't really matter because you as an programmer making use of foreach 
never see it and don't care about it.


I don't see anything like this ever being implemented in COBOL, however.


________________________________
From: IBM Mainframe Discussion List <IBM-MAIN@LISTSERV.UA.EDU> on behalf of 
Bill Woodger <bill.wood...@gmail.com>
Sent: Monday, August 15, 2016 1:46 PM
To: IBM-MAIN@LISTSERV.UA.EDU
Subject: Re: COBOL Unbounded Loops: A Diatribe On Their Omission From the COBOL 
Standard (and a Plea for Understanding)

I've never previously heard of a "loop and a half", so did some digging.

Eric S Roberts, you picked an oft-referenced person, Frank :-)

Here's an example of the discussion (not from Roberts, but referencing him):

"The problem with using goto isn't the keyword itself-rather, it's the use of 
goto in inappropriate places. The goto statement can be a useful tool in 
structuring program flow and can be used to write more expressive code than 
that resulting from other branching and iteration mechanisms. One such example 
isthe "loop-and-a-half" problem, as coined by Dijkstra. Here is the traditional 
flow of the loop-and-a-half problem in pseudocode: -

loop
    read in a value
    if value == sentinel then exit
    process the value
end loop

The exit from the loop is accomplished only by the execution of the exit 
statement in the middle of the loop. This loop/exit/end loop cycle, however, 
can be quite disturbing to some people who, acting on the notion that all uses 
of goto are evil, would write this code as follows: -

read in a value
while value != sentinel
    process the value
    read in a value
end while

Unfortunately, as Eric S. Roberts of Stanford University points out, this 
second approach has two major drawbacks. First, it requires the duplication of 
the statement(s) required to read in a value. Any time you duplicate code, this 
results in an obvious maintenance problem in that any change to one statement 
must be made to the other. The second problem is more subtle and probably more 
damning. The key to writing solid code that's easy to understand, and therefore 
maintain, is to write code that reads in a natural manner. In any noncode 
description of what this code is attempting to do, one would describe the 
solution as follows: First, I need to read in a value. If that value is a 
sentinel, I stop. If not, I process that value and continue to the next value. 
Therefore, it's the code omitting the exit statement that's actually 
counterintuitive because that approach reverses the natural way of thinking 
about the problem. Now, let's look at some situations in which a goto statement 
can result in the best way to structure control flow."

Breezing over the "evil" (straw man technique, that was) we get to two major 
(alleged  by Roberts) drawbacks: "it requires the duplication of the 
statement(s) required to read in a value". No, it doesn't. Unless you are only 
interested in "snippets" rather than programs/systems.

Secondly, and that author was saving the best, more damning, for second, "The 
key to writing solid code that's easy to understand, and therefore maintain, is 
to write code that reads in a natural manner." Oh. Ah, they develop:

"In any noncode description of what this code is attempting to do, one would 
describe the solution as follows: First, I need to read in a value. If that 
value is a sentinel, I stop. If not, I process that value and continue to the 
next value."

And continues "Therefore, it's the code omitting the exit statement that's 
actually counterintuitive because that approach reverses the natural way of 
thinking about the problem."

Mmmm... snippets.

I'm a Mail Opening Operative. I arrive at my desk, there's a pile of mail, I 
open a letter, bin the envelope (it is against policy, but I save any 
nice-looking stamps for my cousin, who I think should collect stamps), see who 
it is addressed to (or if it is "advertising", which Mr Johnson deals with - 
I'm not allowed to throw any actual mail away) and then put it in the correct 
pigeon-hole. Then I pick up the next letter, and repeat the process. When there 
is no more mail, I count each bundle, put elastic bands around each bundle,  
and pass them to the delivery boy (if he's bothered to turn up on time, he's 
always with the girls in the punch room). I fill out a sheet of statistics, 
stamp it (Mr Johnson is terribly upset if I forget that). Lately, it was my own 
idea, and Mr Johnson was *very* pleased at my initiative, I have some 
pre-written pieces of paper to make it extremely clear who each packet is for. 
I'm sure *that boy* doesn't even appreciate it. Then it is on to internal mail, 
until the second post arrives in the early afternoon...

Now, one day, I turn up - *AND THERE ARE NO LETTERS WAITING*. I'm all of a 
flummox, and dial Mr Johnson immediately. He never likes being disturbed this 
early, but this was really *IMPORTANT*.

<shivers briefly and artistically> That was character-acting, that was. Or 
character writing.

Now, which of the above two "snippets" is reflective of Mail Opening?  The one 
where you actually start the work of the loop, and exit the loop in a 
completely normal way, or the one where you do a bit of "priming", and realise 
there is nothing to process, so Mr Johnson needs to know?

Snippets.

I found this (different author, also refers to Roberts), as well, I suppose a 
variant of a loop-and-a-half to process "an array, which shows how it would be 
written with a GOTO:

    i = low_value
loop:
    if i > high_value
        goto endloop
    statements
    i = i + increment
    goto loop
endloop:

Really? Let's think. I put something in "i", and then enter the loop and 
immediately... test "i"? Didn't I just put it there?

    i = low_value
loop:
    statements
    i = i + increment
    if i <= high_value
        goto loop

Is that so difficult? Now, it may be the case that when entering the loop, 
high_value isn't really so high, and happens to be smaller than low_value (in 
which case they are poor names):

    if low_value > high_value
        goto stuff_the_loop
    i = low_value
loop:
    statements
    i = i + increment
    if i <= high_value
        goto loop
stuff_the_loop:

That's the "patch as you go along" approach to the use of GOTO ("I only use it 
when it makes the code easier" usually accompanies it).

    if low_value <= high_value
        execute procedure loop_it
    else
        do something else for the unexpected
    end-if

procedure loop_it
    i = low_value
loop:
    statements
    i = i + increment
    if i <= high_value
        goto loop
end procedure

(In this language, of course, procedures can only be entered by "execute", 
there is no "fall through").

Now, note that "i" is busted, and if "i" is valid outside the procedure (like 
in COBOL) you may not want it exactly like that.

procedure loop_it
    i = low_value
loop:
    statements
    if i < high_value
        i = i + increment
        goto loop
    end-if
end procedure

I'm not suggesting the use of GO TOs, I'm just sayin' that when we did use 
them, they didn't have to be used how the critics of GO TOs thought (imagined, 
fantasised) we used them, because they, apparently, only taught and dealt with 
snippets. Snippets.

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN

Reply via email to