1

disclaimer: I'm a university student who's one-year-new to programming. Please don't slaughter me in your responses as I am still a human being

I have an idea that I want some feedback on. I am currently learning C and we just covered while and do loops. The following is some pseudo-code and an interpretation from the perspective of a compiler in a theoretical sense:

the compiler reads the following lines:

while(conditions){
    body
}

and sees that it is a simple while statement and executes it as such. Then, the compiler reads the following lines:

do{
    body
}while(conditions);

and sees that it is a simple do / while statement since it terminates with a semicolon and executes it as such. Then the compiler reads the following lines:

do{
    body1
}while(conditions){
    body2
}

and this is the definition of my idea, a do + while statement. The compiler knows this is a do + while statement since instead of terminating with a semicolon, the while statement opens a new body using a curly brace and then closes with a curly brace at the end of body2.

In my mind this unifies do and while into a modular feature set where you can either use while, do, or do + while. Functionally, the program would execute body1 at least once because it is not bounded by a condition set, then it would check the conditions of the while loop. If the conditions are not satisfied, the do + while loop would terminate. If the conditions are satisfied, the program would execute body2. After body2 is executed, the program would return to the top of the loop, which is body1, and execute it again (since it is unconditional), and then proceed down to the while conditions, looping over and over until the conditions are not satisfied. From what I can gather, it essentially adds nothing new in terms of base architecture. It simply takes a pre-conditional body1 from do and couples it to a post-conditional body2 from while and loops them together.

This (what I believe to be elegant) solution potentially bridges the gap between having separate functions dedicated to evaluating while conditionals so that you're not clogging up the conditions portion of the while loop with long lines of code, but also can clean up code that is on the cusp of needing its own condition function. Like for example you've got one condition that needs an if statement or something else that requires just a few lines of code. Rather than create an entirely new function when the other conditionals are so simple, you can execute a few lines of pre-conditional code every loop to check the validity of one condition before passing it to while(conditions) and have it be clean and readable.

Is there already an elegant solution to this problem? Would any of you actually use an implementation that looks like this? I look forward to hearing feedback on this idea. Even if it is negative I feel like it was a good thought experiment and I hope some of you feel the same way at least.

13
  • 4
    There's a great answer by (I think) Eric Lippert somewhere on either this site or Stack Overflow itself about the cost of adding a feature to a language, and how the value of the feature has to be overwhelmingly large to justify the amount of work it is to modify everything involved with the language. If you or anyone else can find it, that's very worth reading here. Feb 12, 2021 at 9:34
  • 2
    Voters, we are not on Meta.SE here, where up- and downvotes are for signalling agreement or disagreement. Downvotes here are for bad question, not for bad ideas.
    – Doc Brown
    Feb 12, 2021 at 13:57
  • 1
    @PhilipKendall: I think the article you're thinking of is this one? ericlippert.com/2003/10/28/… Mar 8, 2021 at 16:45
  • 2
    @JörgWMittag: I've talked about the concept of -100 points many times but to be clear that phrasing is not original to me; I got it from C# 1.0 designer Eric Gunnerson. I don't know where his original blog post is now but there is a relevant quote from it here: stronglyemergent.com/blog/2013/negative-100-points Mar 8, 2021 at 16:47
  • 2
    @EricLippert Thanks, I think it was the concept of "-100 points" I was remembering and attributing to you. If you say it originally came from Eric G, I'll try and credit him as well in future; Wayback Machine link to Eric G's post Mar 8, 2021 at 17:24

3 Answers 3

5

There are four obvious grounds for assessing a language feature: aesthetics, implementation cost, benefit, and interaction with other language features. I'll skip aesthetics because it's subjective, and implementation cost because I'm not really qualified. Maybe someone can find a link to the Eric Lippert blog that was mentioned in comments.

Interaction with other language features: block scope.

The conditional while section should start a new block, because automatic locals shouldn't begin their lifetimes unless the while condition succeeds at least once. It should also have access to anything that was visible in the while condition itself, otherwise it's behaving differently to a normal while loop.

However the while condition for a do-while has access to the do block scope, so for consistency this should too.

Now the second (conditional) block needs to be nested in the first (unconditional) one, but this isn't how it would be written.

That is, for consistency it would have to behave like:

do {
    body1;
    if(!conditions) {
        break;
    } else {
        body2;
    }
} while(true)

from a scope perspective (because body2 should be able to see everything mentioned in conditions, which should itself be able to see everything in body1).

I can't think of anywhere else two block scopes are implicitly nested without being written that way.


Benefits: unconvinced

It isn't clear to me that this is an improvement over existing do/while loops. Of course, perhaps I'd need to spend some time rewriting existing code to use these loops before understanding their elegance: I'm only saying that it's not immediately obvious.

We already have three loop forms, and since this isn't an entirely straightforward combination of the existing do/while, we would have to consider this a fourth. Perhaps we can express both do{}while and while{} loops as different partially-degenerate forms of do{}while{}, although I'm not completely sure this successfully keeps the complexity under control.

For comparison, take the extension from try/catch to try/catch/finally in languages without RAII. I can see what specific need it serves, and it doesn't alter scope behaviour or object lifetime much beyond being "like another catch block".

9
  • +1. Thinking about the scope, I would say that is exacty the reason why the suggestion in the question is problematic. To make this suggested language feature follow the principle of least surprise, it should introduce two separate scopes, but that would most often nullify its benefits.
    – Doc Brown
    Feb 12, 2021 at 14:03
  • ... however, I would recommend to reword this answer a little bit, the sentence "That is, it should behave more like ..." sounds like you were really suggesting to change Cs scope rules that way - you are surely not recommending this seriously, I guess?
    – Doc Brown
    Feb 12, 2021 at 14:12
  • Absolutely not! Edited to clarify.
    – Useless
    Feb 12, 2021 at 16:50
  • 1
    I think it's reasonable to worry that the scope behaviour is inconsistent with the rest of the language. That's not a hard "no", but one would have to do some work to justify claiming that the inconsistency is either not a real problem or that it is outweighed by the benefits.
    – Useless
    Feb 14, 2021 at 21:16
  • 2
    Since readability is subjective and heavily influenced by familiarity, it's not easy for someone with a year's experience to convince experts that new syntax is an improvement. After a decade of reading and writing C, most changes make it harder to understand rather than easier, because you have to re-learn mental models, reading habits and muscle memory. So you have to justify not only that effort, but also the standardization and tooling costs mentioned elsewhere.
    – Useless
    Feb 14, 2021 at 21:21
4

A do...while is only different from a while... in one respect - in a do...while the body is executed at least once, whereas in a while...do it may not be executed at all.

Your do + while statement can easily be achieved within the existing C syntax as follows:

do
{
    body1;
    if ( !conditions ) break;
    body2;
} while true;

The C language is already complicated enough, without adding more complexity!

1
  • 1
    I completely agree with you that a solution already exists, but I'm not quite sure I agree on how much your proposed solution is less complex particularly where readability is concerned. I do however, really appreciate your response because my professor and I have decided to try and implement this as a change in the pre-compiler to see how the do + while performs and your input has given me a good thought exercise to perform so I greatly appreciate it.
    – Jack
    Feb 13, 2021 at 5:58
2

This is a reasonable construct.

My preference with looping is either:

  • when we know the count, counted loop, e.g. on count of N:

for (int i = 0; i < N; i++ ) ...

-or-

  • when we don't know the count, then "infinite loop":
    for (;;) { // or while (1) {
        // unconditional stuff that occurs (before) each iteration
        if ( condition ) break; // termination condition
        // conditional stuff for an iteration
    }

As an instructor, I find that many students find while and do while difficult for writing new code, and as such, my conclusion is that these constructs are optimizations for reading code, but not great for initially writing code.  So, I encourage using either of the above two forms, as they lend themselves more to writing loops.  Should either the unconditional stuff or the conditional stuff be "nothing" then we can convert loops of the latter form into while or do while forms, respectively, if we so desire (and sometimes I don't).

My students find these forms easier to work when writing code, since it allows them to put down in source more what they're thinking than the other forms.

Let's also note the in the "when we don't know the count" form, we can provide more than one exit condition, mixed into the loop body.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.