Programming: Do-While or Repeat-Until

I know what While/Do-While/Repeat-Until loops are. This is a question about terminology.

I was looking at Do-While loops on Wikipedia, because I wanted to see if DO WHILE was now a standard construct in Fortran, or a vendor-specific extension. When I was first learning Fortran, we had to make these loops ourselves, with GOTOs.

As I was taught, a Do-While loop had the test prior to the loop, and the body might never be executed. Repeat-Until loops had the test at the end, and the body was executed at least once. There was also a loop with the test in the middle, but I don’t recall if it had a specific name.

As Wikipedia has it Repeat-Until is another name for Do-While, and in both, the body is executed at least once. What I call Do-While is called a While loop there.

Both those pages are cited for not showing sources, though, and the Do-While page is unreliable. Go down to the Fortran examples, and the first example is indeed a post-test loop, but gives the wrong value if counter is set to zero before the loop (actually, it enters an infinite loop, but a change to the test could fix that). The second example correctly sets factorial to 1 if counter is zero, but is a pre-test loop. I didn’t check all the examples, but the Bash example is also a pre-test.

So, is there a standard terminology? Does it depend on what language you’re using? What language you first learned? What do you use?

C++ has separate while and do-while constructs. The do while



do
{
    expr_1;
}
while (cond_1);

while (cond_2)
{
    expr_2;
}


In that case, expr_1 is evaluated at least once, but expr_2 may not be if cond_2 is false at the end of the first loop.

With Fortran, I’m pretty sure do while is standard.



flag = true
do while (flag)
  <stuff>
  if (something) then
    flag = false
  endif
enddo


I’m also pretty sure one should never use goto, ever.

C/C++ has while loops which do the same thing.



while (condition)
{
<stuff>
if (something)
  condition = false;
}


I prefer the loops like:

while (condition)
{
stuff
}

Because when I’m reading the code I know what the break condition is as I’m reading the stuff block. If the break condition is at the end, I have to page down to the end of the loop so I know the break condition and then I can go back to the top of the stuff block and continue reading.

That means I will write code like this:

keepGoing=true
while (keepGoing)
{

}

instead of code like this:

do
{

} while (keepGoing)

What I’m interested in here is, is whether there is a standardized terminology. In Fortran, there is a loop structure

DO WHILE (Condition)

END DO

I would call that a “Do-While loop”, not a “While Loop”.

In C++, there is the form

do {

} while (condition)

Wikipedia calls that a “Do-While loop”. The two loops behave differently, even though they both have the words “do” and “while”. The first has the test before the body, and the second has it after.

Is there a standard terminology, not language-specific, for whether a “Do-While loop” has the test at the beginning or the end?

If I write the first loop, and call it a “Do While loop”, someone might say “Actually, that’s a While loop, not a Do-While.” Would they be correct, in some objective sense?

I can only give you my opinion as someone that’s been programming for a long time and in many environments:

If you say “xxxxx WHILE” I assume you mean the test is before any iterations of the loop. If you say “xxxxx UNTIL” I assume you mean the test is after at least one iteration.

Yes, there is a standard terminology. Unfortunately, it’s a different terminology for every programming language. :wink:

Given that I started out as a FORTRAN programmer (in the 60’s), I always felt that the FORTRAN approach was best. But these young whippersnappers, though…

There are many different syntactic and semantic constructs for loops. Among the semantic variations to consider, are several factors. Whether the loop always executes at least once is important, so a loop of the form WHILE (expr) { … } allows a loop to execute only while a expr is true. Sometimes you want a loop to execute at least once under any condition, and then a construct like DO { … } WHILE (expr) is useful. The loop will always execute once, and then exit if expr is false following the last pass through the loop. When loops have an incremental expression involved, such as FOR (init;condition;increment) { … }, then the exact order of the processing can be very important. In some languages such a loop will always execute at least once, while in others if condition is initially false the loop will not execute at all. In simplistic constructs, the init, condition, and increment expressions may only be evaluated once prior to executing the loop, so changing variables used by these expressions in the body of the loop will have no effect. And depending on the language, different implementations may have subtle differences also.

There are many different ways languages treat these structures, and to address the question in the OP, there is no standard. These are the subtleties of languages that make the difference between passing familiarity with a language, and proficiency. However, in most cases, it is best to code so that these factors are unimportant. Modern language inplementations are fast and efficient. If you do not want a loop to execute even once, enclose it in an IF structure so that it will not be used when unnecessary. Do not rely on the condition of incremented values processed by the loop, if you want the variable X to have some specific value when the loop terminates, set it that way yourself. This makes the functionality of the code more obvious, without the person who has to fix it someday needing to understand your thought process when evaluating the code.

There is no serious need for any construct except a generic loop which iterates until a specific break command is executed. All other processing could be performed by explicit code before, during, and after the loop. The various looping constructs were originally designed to be shorthand notations to simplify coding. Because of the variations you’ve noticed, and others, this leads to more problems than any benefit obtained from efficiency in coding. The point of programming constructs now is clarity.

I’ve noticed that most programmers tend to pick a loop construct that they like and use it for almost everything. Those that tend to use all of the loop constructs available, also tend to be the ones likely to introduce bugs from an unintended effect of the loop construct, or at least confuse the next person to work with the code.

AARRGGHH!!! Silly programming purist!!!

Many years ago, I approached one of my fellow programmers and asked for help trying to debug one of my C programs. She spotted a GOTO in my code (in an area that had nothing to do with the problem) and refused to help me until I’d removed it.

A couple of weeks later I forwarded her an article about GOTOs. Someone had run an analysis program counting GOTOs in the source code of popular C programs and operating systems. It turned out that AT&T Unix - which she despised as being a product of the corporate devil - had one GOTO every (I’m making the exact numbers up here) 280 lines of code. And Berkeley Unix (which she absolutely adored) had one every 190 lines of code.

I don’t think she ever spoke to me again.

I use a GOTO whenever it is the cleanest/correct choice - which absolutely happens, once in a while.

I could write perfectly structured and elegant code with just GOTO’s - it’s not so much the instruction it’s how you use it.

**Tripolar **nailed it.

There is no industry-wide language-agnostic universal terminology. Though there may be folks who mistakenly think their personal terminology is universal.

For values of “may be” that include “are many”.

… and write it up in Wikipedia.

Thanks everyone.

I was being polite. The software industry certainly attracts more than it’s fair share of under-informed know-it-alls.
The less you know, the more sure you are you know all you need to know. Seems like that applies to quite a few folks who sling code for a living. IMO, it’s more the folks working in small environments than in big.

Agreed. It’s become conventional to hate the GOTO - and although there are valid reasons to avoid it a lot of the time, it’s not useless - it’s just a bit prone to permitting the creation of fragile code.

Once code is compiled, the result contains a whole load of GOTOs (although arguably this is OKbecause the compiler shouldn’t use them in a sloppy way.

Quoth RaftPeople:

While I agree with this in principle, that “once in a while” is extremely rare. In close to two decades of C programming, I don’t think I’ve ever once had occasion to use it.

Of course, now I’m stuck with F77, where it’s kind of unavoidable, for lack of most other loop constructs.

GOTOs are evil.

It may seem like a simple fix, but use just one, and it will bite you (or someone else) in the ass 5 years later.

Spoken like someone who never bothers with error handling in their code. :rolleyes:

Back in the '80s I built an interactive front-end for our firm’s forecasting software. In FORTRAN, because that’s what we used at the time. We expanded from one one to two interactive providers, and I had to convert the package, originally written for an (if I remember correctly) IBM VM360/370 OS to also run on a DEC OS.

Now in those days, different implementations of FORTRAN - particularly interactive implementations - often used unique function calls. The second system often used mandatory error exits (“call dosomething(a,b,&1000)” where 1000 was a statement number the routine would exit to if it encountered an error) where the first system didn’t.

I dutifully added error exit logic wherever it made sense, but there were a ton of places where I*** knew*** the called subroutine would never run into problems, but I had to give it an error exit anyway so I encoded a generic “oops()” routine that just printed out the word “oops” and stopped the program. The package ended up littered with hundreds of calls to the “oops()” routine.

You can guess what resulted. For years afterwards, scenarios like the following occurred:

analyst walks into my office: “I got an ‘oops’.”

me: “How did you get the ‘oops’?”

analyst: “I dunno, I was just working away when suddenly the program said ‘oops’ and stopped.”

I had to write a Fortran program for Algebra II in college. The teacher taught us Do-While but, having learned BASIC a few years prior, I noticed that the two languages were extremely similar, so when I looked at the details of the assignment and realized that gee if I do it like this and then that and… I just wrote it in BASIC as a “pseudocode”, thinking “well, anything where the computer barfs back ‘syntax error’, I’ll just change”.

Turns out the only thing the computer didn’t like was that Fortran has a specific command for “square root”; my For-Thens were just fine thank you very much. I think the reason I understand “For… Then” better is that it works as a direct translation from Spanish; the other options don’t.

Is GOSUB ok? I didn’t use GOTOs, but I used GOSUBs… way I see it, my SUBs were just what a .dll would be nowadays