<p>Anyone who's used C-family languages enough will have seen or used a &quot;loop-and-a-half&quot;, which can be written in one of two ways:</p>
<pre class="lang-c prettyprint-override"><code>foo();
while (condition) {
  bar();
  foo();
}

while (1) {
  foo();
  if (!condition) break;
  bar();
}
</code></pre>
<p>These examples show the basic structure of the &quot;loop-and-a-half&quot;; <code>foo();</code> and <code>bar();</code> here are placeholders for any statements. Often, the &quot;foo&quot; part reads some input, the &quot;condition&quot; checks that the input hasn't ended, and the &quot;bar&quot; part uses the input data somehow.</p>
<p>The former spelling involves code duplication, and the latter is error-prone (it's possible to forget the <code>break</code> statement and cause an infinite loop). It's possible to avoid both problems with a <code>goto</code>:</p>
<pre class="lang-c prettyprint-override"><code>goto middle_of_loop;
while (condition) {
  bar();
middle_of_loop:
  foo();
}
</code></pre>
<p>but I've never seen this in practice, and newer languages tend not to have <code>goto</code> in the first place. Besides, <code>goto</code> has <a href="https://langdev.stackexchange.com/q/581/15">its own problems</a>.</p>
<p>How could a C-family language make these easier to read and write? Does any language have a dedicated syntax for this?</p>

<c><loops>
How could a language make the loop-and-a-half less error-prone?
CC BY-SA 4.0
2023-06-30T23:27:45.690Z
I've never really considered the second version to be error-prone. It concisely expresses the logic, and forgetting the break is simply a logic error.
Barmar
CC BY-SA 4.0
2023-07-23T09:50:40.343Z
Related: https://langdev.stackexchange.com/questions/95
Karl Knechtel
<p>A least-change approach would be to make it a compiler error if you write a <code>while (true)</code> or <code>for (;;)</code> loop without a loop-exiting statement (<code>break</code>, <code>return</code>, or <code>throw</code>) somewhere inside it.  This would solve the “forgetting the <code>break</code> statement” issue similarly to how C# dealt with C's error-prone fall-through between <code>case</code> blocks.</p>
<p>Perhaps some special syntax could be introduced for the case when you deliberately do want a loop to run “forever” (until the process is interrupted/terminated).</p>

CC BY-SA 4.0
2023-06-30T23:13:01.453Z
2023-06-30T23:13:01.453Z
dan04
CC BY-SA 4.0
2023-07-01T00:02:47.083Z
I think `throw` shouldn't be allowed as the only exit from such a loop, because other statements like `baz();` can also throw. If you have a separate "infinite loop without break" keyword like `forever` then `throw` could still be allowed in those loops though. This is just my opinion, but I think if you have separate keywords for the two kinds of loops then the distinction should be that `while` loops can complete normally (so the code after them is reachable) whereas `forever` loops can't complete normally (but can still complete abruptly by throwing).
kaya3
CC BY-SA 4.0
2023-07-03T13:47:42.687Z
Good point. Designing new syntax (or citing other existing syntax examples) is interesting, but this answer focuses on the specific reason OP finds the original syntax error-prone.
Karl Knechtel
<p>I've sometimes wished for a loop like</p>
<pre class="lang-c prettyprint-override"><code>do {
  foo();
} while (condition) {
  bar();
}
</code></pre>

CC BY-SA 4.0
2023-06-30T23:01:25.703Z
2023-06-30T23:01:25.703Z
Jeremy
CC BY-SA 4.0
2023-07-01T07:37:10.040Z
That looks pretty readable to my eyes.
Jack Aidley
CC BY-SA 4.0
2023-07-01T16:07:31.620Z
I see this going really wrong when the `do` is off-screen reading a longer code example. The `while (condition) { bar(); }` part would be valid by itself, but now when control reaches that final `}`, it no longer goes to the "matching" `{`, but instead to the `do {` one. The `}` before `while` on the same line is a useful contextual clue, but that wouldn't apply in e.g. a language with Python-like braceless syntax.
Karl Knechtel
CC BY-SA 4.0
2023-07-01T20:59:30.520Z
This seems elegant to implement. Instead of there being a separate `do {} while ()` construct, there can just be a `while ()` with an optional `do {}` prefix.
CPlus
CC BY-SA 4.0
2023-07-03T14:34:49.183Z
I would be very confused if I saw this in code. Is `foo()` ran only once before the loop, and then `bar()` ran at every iteration? Or is `foo` ran at every iteration, and then `bar()` is ran only once after the loop?
Stef
<p>Rust can achieve this without <code>break</code> or code duplication, since blocks are expressions:</p>
<pre class="lang-rust prettyprint-override"><code>while {
    foo();
    condition
} {
    bar();
}
</code></pre>
<p>Unfortunately this is a bit of an idiom, because the keyword <code>while</code> is separated from the actual <code>condition</code> for the loop; and the condition's location is marked by the <code>} {</code> line after it, which is weird. Perhaps if people get more used to the loop-and-a-half being written this way, it will become more intuitive.</p>
<p>Nonetheless it gets the job done, and the only language construct you need is block-expressions, i.e. a block delimited by braces which contains any number of statements followed by one expression, and the block's value is the value of the final expression.</p>

CC BY-SA 4.0
2023-06-30T23:25:10.457Z
2023-06-30T23:25:10.457Z
kaya3
CC BY-SA 4.0
2023-07-01T00:05:37.880Z
I suppose you could achieve the same thing in, say, JS or Swift using an IIFE, but that gets a little punctuation-heavy, and it changes the semantics of `return` in a way that may not be desirable.
Bbrk24
CC BY-SA 4.0
2023-07-01T07:11:26.350Z
`sh`, of all languages, also has this, just with a different spelling: `while foo; condition; do bar; done`.
HTNW
CC BY-SA 4.0
2023-07-02T03:31:53.377Z
it splits the loop block into two which could be p a problem if you want to share a block scoped variable between the two parts.
Jasen
CC BY-SA 4.0
2023-07-02T03:36:01.753Z
@Jasen That is a good point, but at least in Rust you can declare the variable outside of the loop, assign to it in the "foo" part, and Rust will know that it's definitely initialised when you use it in the "bar" part.
kaya3
CC BY-SA 4.0
2023-07-02T05:57:32.400Z
I disagree that this is a good solution for this idiom. Firstly, it's a little surprising even to experienced users of Rust. Secondly, almost every time I've seen someone try this (from beginners on the Discord to colleagues at work), it's ended up with issues relating to ownership or aliasing, eg. `foo()` needs to own something that `bar()` needs later. And then you end up stuffing the output into an `Option` on the stack outside the loop, and presto, you've reinvented the `Option` based iterators but with less clarity and language support.
detly
CC BY-SA 4.0
2023-07-02T13:30:03.963Z
@detly I didn't say it is a good solution; I said it "gets the job done" but is "unfortunately a bit of an idiom". Your point about ownership and lifetimes is largely addressed by my previous comment, but also not relevant unless you are designing the loop syntax for a language which has a Rust-like borrow checker (i.e. a tiny minority of languages).
kaya3
CC BY-SA 4.0
2023-07-02T17:46:47.860Z
It's also very similar in Forth. `BEGIN foo condition WHILE bar REPEAT`
Criticize SE actions means ban
<p>In languages with a C-style comma operator, you can use</p>
<pre><code>while (foo(), condition) {
    bar();
}
</code></pre>

CC BY-SA 4.0
2023-06-30T23:31:01.213Z
2023-06-30T23:31:01.213Z
Barmar
CC BY-SA 4.0
2023-06-30T23:59:21.767Z
You’re not wrong, but as a matter of personal preference I think it’s ugly. Besides, this assumes that “foo()” is only a single expression, which isn’t always the case.
Bbrk24
CC BY-SA 4.0
2023-07-01T07:29:37.257Z
@Bbrk24 No, it doesn't. You can have as many as you want with the comma operator. I agree it's not a particularly readable style though.
Jack Aidley
CC BY-SA 4.0
2023-07-01T12:44:58.180Z
@JackAidley They still need to be _expressions_ and not, say, nested loops.
Bbrk24
CC BY-SA 4.0
2023-07-01T19:09:51.500Z
True, But Lampson's Law applies: you can move that loop into a function and call the function.
Barmar
CC BY-SA 4.0
2023-07-01T20:20:18.987Z
This is pretty similar to the Rust approach described in kaya3's answer
user
CC BY-SA 4.0
2023-07-01T23:10:47.170Z
@Bbrk24 Nothing prevents you from designing loops as expressions. Also GNU C's [Statement Expressions](https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html).
Longinus
CC BY-SA 4.0
2023-07-02T17:48:54.280Z
As we see in the other answers, other languages (as well as a GCC extension to the C language) solve this by allowing the condition to really contain multiple statements instead of using the comma operator hack.
Criticize SE actions means ban
CC BY-SA 4.0
2023-07-03T12:30:49.597Z
@Longinus: Nothing except readability!  Remember, we're looking for a usable idiom for real code that's easy to write and maintain overall, not *just* achieving the goal of not repeating `foo` or `bar`, or code-golf. (If code-golf was the goal, though, good point about statement-expressions allowing `{ anything }` to be an expression between commas if you structure it right).  If `foo()` is complex, a lambda with some captures is probably a good bet to make the pain of repeating it minimal, or to ease the readability of an idiom like this.
Peter Cordes
CC BY-SA 4.0
2023-07-03T14:40:24.663Z
@PeterCordes There is "real code that's easy to write and maintain overall" written in Zig, Clojure and F# that use looping expressions. Also many programmes use recursion as an iteration mechanism, which most of the time appears as self-referential expressions. Haskell also has libraries where the entire concept of a "loop" is generalised to various userland morphisms.
Longinus
CC BY-SA 4.0
2023-07-04T14:35:27.540Z
Doesn't that allow the compiler to reorder foo() and condition in ways that were not allowed in the original?  Why not just use [C block expressions](https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html)?
Mike Samuel
CC BY-SA 4.0
2023-07-04T14:53:47.483Z
@MikeSamuel The comma operator guarantees to evaluate left to right. Block expressions are a GCC extension. Of course, if you're designing your own language you can add it.
Barmar
<p>A frame challenge: the problem isn't really with the loop construct itself, but with ad-hoc bundling of the &quot;half&quot; loop with the condition check. This is a problem that should be solved elsewhere, <em>mainly by the programmer</em> but perhaps also by making (possibly anonymous) function syntax easier in the language.</p>
<p>Note that the problem disappears entirely, even in C, if the first half of the loop really is wrapped up in a <code>foo</code> function <em>and that function returns</em> the desired <code>condition</code> value; then we can simply write</p>
<pre><code>while(foo()) bar();
</code></pre>
<p>In C (or C++), even if that doesn't hold up, we can <a href="https://stackoverflow.com/a/52615">exploit the comma operator</a> - so, in this case:</p>
<pre><code>while(foo(), condition) bar();
</code></pre>
<p>So really, problems occur because there isn't already a <code>foo</code> and there is some resistance to making it. My experience - across multiple programming languages and something like 35 years of writing code - has consistently been that the <em>common</em> case, by far, is that the <code>foo</code> logic has the <em>explicit purpose</em> of setting things up so that the loop condition can be evaluated, and that this process is <em>coherent and nameable</em>. As such, the resistance to creating a separate function usually just seems lazy to me. (Of course, there are language-specific idioms for one-off functions, like blocks and IIFEs (really popular in Javascript). But I think code clarity often suffers this way. Naming things is quite useful.)</p>
<p>Another thing that can help is to make it easier to work with generators and iterators. For example in Python, reading from a file produces an empty result if and only if we are at the end, which allows a clever idiom for <a href="https://stackoverflow.com/questions/4566498">reading a binary file in chunks</a>.</p>
<hr />
<p>As a footnote: even in the cases where we'd want to use the comma operator in C or C++, we might want to ask ourselves <em>why</em> the code is designed that way. In the linked answer, we suppose that we need the length of a string that is populated by an I/O function (granted this appears to be a C++ example on what was asked as a C question). Sure, it would be contrived (and inflexible) to have that function report whether the resulting string meets some specific condition, and perhaps awkward to make a wrapper. Even just having it report the length seems arbitrary (and makes it harder to give the function a good name).</p>
<p>But - it could simply return the string itself by reference, and then <code>while(read_string(s), s.len() &gt; 5)</code> simply becomes <code>while(read_string(s).len() &gt; 5)</code>. Similarly in C: if we pass a pointer to a buffer, just return that pointer as well (or perhaps a more useful one inside the buffer). The standard library <em>already works that way</em>, after all. (Some languages, like Python, resist the idea of a function returning a value and also having side effects, for well-considered reasons. But then we might ask if we wouldn't be happier with a new object anyway. Incidentally, the new-since-3.8 walrus operator can enable some tricks comparable to what I showed with the comma operator.)</p>

CC BY-SA 4.0
2023-07-01T12:06:48.480Z
2023-07-01T12:06:48.480Z
Karl Knechtel
CC BY-SA 4.0
2023-07-01T16:21:24.817Z
*"Note that the problem disappears entirely, even in C, if the first half of the loop really is wrapped up in a foo function and that function returns the desired condition value;"* ─ this isn't a practical solution to the problem, because usually the "foo" part of the loop-and-a-half declares some variable (e.g. `let line = input.readLine();`) which is used in the condition and also in the "bar" part. Factoring out the "foo" part into a separate function moves the variable `line` out of scope for the "bar" part.
kaya3
CC BY-SA 4.0
2023-07-01T16:23:26.550Z
@kaya3-supportthestrike I could have sworn I originally planned to address that, but now I'm not really sure what to say about it. It definitely is a complication.
Karl Knechtel
CC BY-SA 4.0
2023-07-01T20:59:24.417Z
@kaya3-supportthestrike One approach is to make a new object first so that `let line = input.readLine(); while (line) { bar(line); }` becomes `while (reader.readLine()) { bar(reader.line); }`
krubo
CC BY-SA 4.0
2023-07-02T12:19:14.750Z
Isn't the instantiation of a variable to be used for a loop, but declared outside the scope of a loop some sort of anti-pattern, as @krubo implies?  Isn't this entire question based upon anti-pattern semantics? cf. https://softwareengineering.stackexchange.com/questions/142144/whiletrue-and-loop-breaking-anti-pattern
Konchog
<p>Instead of having a separate condition expression, have the loop body return a <code>Result</code>, and repeat the loop until it's an error (i.e., &quot;while it succeeds&quot;).</p>
<p>Using this style, you can rewrite all sorts of control flows by just changing where in the body the test is performed:</p>
<pre><code># Traditional `while`:
while {
    test_condition()?
    foo()
    bar()
}

# Loop-and-a-half:
while {
    foo()
    test_condition()?
    bar()
}

# Do-while
while {
    foo()
    bar()
    test_condition()?
}
</code></pre>
<p>Where <code>fn()?</code> is a Rust-style operator that immediately returns an error if the call fails. You can think of it as an assert, and the loop stops when the body fails an assertion.</p>
<p>With a little bit of optimizing, it should perform the same as a traditional <code>while</code> loop.</p>
<p>You can also extend it to boolean operators, where a <code>false</code> result is considered an error:</p>
<pre><code>while {
    foo()
    (count &lt; 10)? # or count &lt;? 10
    bar()
}
</code></pre>
<p>This is better than the <code>if (!condition) break</code> because the condition can be used inline, and the user is less likely to forget the &quot;break&quot; since there's no obligatory condition at the start.</p>
<hr />
<p>It can also replace other tricky scenarios, like an <code>if</code> that must operate on an <a href="https://docs.python.org/3/whatsnew/3.8.html#assignment-expressions" rel="noreferrer">assigned value only if it succeeds</a>. This is a feature most languages need special syntax for, but happens naturally if the condition is part of the body:</p>
<pre><code>if {
    match = re.match('\d+', str)?
    print(&quot;Got a number:&quot;, match)
} {
    match = re.match('[a-z]+', str)?
    print(&quot;Got a word:&quot;, match)
} {
    print(&quot;No match&quot;)
}
</code></pre>

CC BY-SA 4.0
2023-07-02T15:41:57.413Z
2023-07-03T10:30:56.923Z
2023-07-03T10:30:56.923Z
BoppreH
CC BY-SA 4.0
2023-07-03T13:30:51.123Z
I don't know whether to be disgusted or amazed. As elegant as this looks in shorter code, it may be difficult to find the `?` in a longer loop, and this is even more error-prone / easy to forget than `break`. But sure, `Bool = Result<Void, Void>`, why not.
Bbrk24
CC BY-SA 4.0
2023-07-03T14:06:45.413Z
@Bbrk24 Haha, that's a great reaction. I have a whole self-hosted language based on this trick, and so far it's been working really well, especially since you can interleave multiple condition tests as needed. But I totally understand the shock.
BoppreH
CC BY-SA 4.0
2023-07-04T01:46:26.463Z
I really like this concept, but I wonder that separating the condition from the 'while' impedes readability. Eg.: while { ... long procedure...  condition? ...more procedure... condition2? } - doesn't read very well. Perhaps renaming from "while" to "loop" or even "loop if" might reduce the disconnect between the syntax of the language and the syntax of English (assuming English). A potential advantage of "loop if" is you then have "loop for" in a matching style.  The "if" statement is less bad, but could still be confusing: if {condition1? condition2? foo()}. Is that condtion1 && condition2??
Infinite_Maelstrom
<p>If your only concern is someone missing a <code>break</code>, you could allow syntax like <code>while(!break)</code>, <code>while(!break &amp;&amp; !throw)</code> or whatever other loop-exiting mechanisms your language has. It would be equivalent to <code>while(1)</code> except it would be an error not to have the specified means of exiting the loop inside.</p>
<p>Also if your language has named breaks like in C. T. Zahn’s 1974 paper that I’m having trouble locating but that look like the following, perhaps you would be able to use that feature to require a break with a particular name.</p>
<pre><code>for(item in items) {
    if(item.is_interesting()) {
        break found_interesting(item);
    }
    if(item.breaks_invariant()) {
        break epic_fail;
    }
}
when found_interesting(item) {
    do_something(item);
}
when epic_fail {
    crash();
}
</code></pre>
<blockquote>
<p>Does any language have a dedicated syntax for this?</p>
</blockquote>
<p>Forth:</p>
<pre><code>BEGIN part1 WHILE part2 REPEAT
</code></pre>
<p>If <code>part1</code> leaves a false value on the top of the stack, exit the loop. Nothing prevents <code>part1</code> from doing a lot of other work prior to calculating whether to break.</p>

CC BY-SA 4.0
2023-07-02T14:49:49.723Z
2023-07-02T14:49:49.723Z
Roman Odaisky
CC BY-SA 4.0
2023-07-02T15:33:19.200Z
Is [this](https://link.springer.com/chapter/10.1007/3-540-06859-7_133) the paper you're looking for?
Bbrk24
CC BY-SA 4.0
2023-07-03T16:33:39.937Z
@Bbrk24 Yes, that’s the one. Looks very useful, I wonder why it hasn’t seen any adoption in 50 years.
Roman Odaisky
<p>The following might be highly unidiomatic in many C-like languages, but you did ask &quot;does any language have a dedicated syntax for this&quot;, which suggests that you might be looking for ideas from other families.</p>
<p>gcc does tail-call optimisation and C++ has lambdas, so I hope you grant that those are features a C-family language can have. With this in mind, F# would do the following:</p>
<pre><code>let rec loop () =
    foo ()
    if condition then
        bar ()
        loop ()
loop ()
</code></pre>
<p>So what you want could plausibly be spelled as follows, where I've invented some syntax</p>
<pre><code>nocapture void loop() {
    foo();
    if (condition) {
        bar();
        tail loop();
    }
}
loop();
</code></pre>
<p>I argue that this doesn't have code duplication (unless you count the initial invocation of the loop). I also argue that it's extremely clear what is going to happen when, such that &quot;forgetting the condition&quot; is a very unnatural move.</p>
<p>The downsides:</p>
<ul>
<li>the mild one that it's eight lines rather than five;</li>
<li>the substantial one that depending on how the closure is implemented, an insufficiently smart compiler might copy local state to the heap, or it might become much more verbose as you have to specify what state is captured and where. The hypothetical language probably wants specific support for this pattern to make a user comfortable relying on it. (I gestured to this with <code>nocapture</code> and <code>tail</code>, but with an appropriate linter or a sufficiently smart compiler you wouldn't need those keywords.)</li>
</ul>
<p>If you're designing a language which is happy to have a complicated spec anyway, then I'm sure you could special-case this pattern into the syntax to make it much shorter.</p>

CC BY-SA 4.0
2023-07-01T10:13:07.337Z
2023-07-01T10:13:07.337Z
Patrick Stevens
CC BY-SA 4.0
2023-07-01T17:55:26.067Z
Now that you mention it, isn’t this how `loop`-`recur` works in Clojure? Having that as a macro or as a keyword pair could work just as well in a C-family language.
Bbrk24
<blockquote>
<p>Does any language have a dedicated syntax for this?</p>
</blockquote>
<p>Bourne-shell type languages (sh, bash, zsh, etc.) have it:</p>
<pre class="lang-sh prettyprint-override"><code>while
  foo
  condition
do
  bar
done
</code></pre>
<p>To be clear, I'm answering on having a syntax that's specifically dedicated to this type of loop construct.</p>
<p>Other languages like Rust, Lisp-based languages, Ruby, Haskell, or even the same Bourne-shell based languages, will support very similar constructs by way of consequence from having a syntax that generically turns lists of statements into expressions. That enables their use in the loop condition, which is generally limited in most languages to an expression. In bash, that can look like this:</p>
<pre class="lang-sh prettyprint-override"><code>while {
  foo
  condition
}; do
  bar
done
</code></pre>
<p>Ruby:</p>
<pre class="lang-ruby prettyprint-override"><code>while (foo; condition)
  bar
end
</code></pre>
<p>Haskell:</p>
<pre class="lang-haskell prettyprint-override"><code>whileM (do { foo; condition }) $ do
  bar
</code></pre>
<p>Common Lisp:</p>
<pre class="lang-lisp prettyprint-override"><code>(while (progn (foo) (condition))
  (bar))
</code></pre>
<p>JavaScript (not sure lambdas are fair, though):</p>
<pre class="lang-javascript prettyprint-override"><code>while ((function () { foo; return condition; })()) {
  bar;
}
</code></pre>
<p>The <code>while</code> syntax in Bourne-shell type languages however, instead of taking a single command/expression for the condition, will take a list. From the bash manpage:</p>
<blockquote>
<p>while list-1; do list-2; done</p>
<p>The while command continuously executes the list list-2 as long as the last command in the list list-1 returns an exit status of zero.</p>
</blockquote>
<p>This is why it requires the <code>do</code> keyword to signify the end of one list and the start of the other.</p>
<p>I am aware that this doesn't show a significant functional difference if any for the language user. However, it is the only language I could think of that has a syntax dedicated to this as was asked, and I do think it's interesting to note, at least for this site, because having non-generic syntax rules like this does complicate the language. The idea of the return status of the last command being the return status of a list is not just documented where &quot;lists&quot; is documented, but also here where <code>while</code> is documented. And that has a sort of avalanche effect, because then <code>set -e</code> also has to make a special note on the lists used for <code>while</code> conditions, despite <code>set -e</code> not being about loops.</p>
<blockquote>
<p>-e</p>
<p>Exit  immediately  if a pipeline (which may consist of a single simple command), a list, or  a  compound  command (see SHELL GRAMMAR above), exits with a non-zero status. The shell does not exit if the  command  that  fails  is part  of  the command list immediately following a while or until keyword</p>
</blockquote>

CC BY-SA 4.0
2023-07-02T04:44:27.703Z
2023-07-03T23:39:46.697Z
2023-07-03T23:39:46.697Z
JoL
CC BY-SA 4.0
2023-07-03T13:45:25.370Z
This seems to be essentially the same idea as in Rust (Kaya's answer).
Karl Knechtel
CC BY-SA 4.0
2023-07-03T21:58:16.823Z
@KarlKnechtel I don't think so. The Rust one is following the idea that blocks of statements are expressions and their `while` syntax accepts an expression. Here, the `while` syntax specifically states it takes a "list": "list-2 is executed as long as the last command in list-1 returns a non-zero exit status" (bash manpage). This is why it has the `do` keyword to signify the end of list-1 and the start of list-2. If the syntax were instead to take a command (or pipeline) instead of a list, then it'd need either a `{}` or `()` compound command and I would agree with you that it's the same idea.
JoL
<p>In some languages, like Dart for example, assignments also return the value. While it's not applicable to all situations, it removes the necessity of a loop-and-a-half in some cases. For example you could write this while loop</p>
<pre><code>String? input = stdin.readLineSync()
while (input != &quot;end&quot;) {
    print(input);
    input = stdin.readLineSync()
}
</code></pre>
<p>as this instead</p>
<pre><code>String? input;
while ((input = stdin.readLineSync()) != &quot;end&quot;) {
    print(input);
}
</code></pre>

CC BY-SA 4.0
2023-07-03T06:29:17.210Z
2023-07-03T06:33:08.360Z
2023-07-03T06:33:08.360Z
Ivo
<p>Directly as</p>
<pre><code>loop
   foo;
   exit when not condition;
   bar;
end loop;
</code></pre>
<p>in either Ada or VHDL for example.</p>

CC BY-SA 4.0
2023-07-02T15:42:24.787Z
2023-07-02T15:42:24.787Z
user_1818839
CC BY-SA 4.0
2023-07-02T17:34:25.720Z
That's what I would have suggested, except that you beat me to it, and I would have recommended outdenting the "exit when" line to match up with "loop" and "end-loop" when there aren't any nested control structures.  Perhaps I might also add a syntactic marker that would be required before any statement which contained a statement that would exit the loop, with a recommendation that such a marker be aligned with the start and end of the loop.
supercat
CC BY-SA 4.0
2023-07-03T13:41:56.663Z
It's not clear to me what `exit when not condition` is really doing better (= in a less error-prone way) than `if (!condition) break`.
Karl Knechtel
CC BY-SA 4.0
2023-07-03T15:04:31.353Z
@KarlKnechtel mainly that this is what `exit` is for; `break` in C has other uses. So in a trivial example, I'd agree both are equally error-resistant, but more complex code with nested if and case statements / switches can become challenging. Both Ada, VHDL of course still have `while` and `for` loops, which are just syntactic sugar over this basic loop. (VHDL allows labelling loops, and `exit <label> when ...` for nested loops)
user_1818839
<p>In my experience, this &quot;half-loop&quot; occurs for a couple of language-inherent reasons:</p>
<ol>
<li><code>foo()</code> needs to mutate some state related to the loop, usually in some fallible way, and <code>bar()</code> needs to non-fallibly get at <em>some</em> of the results; and</li>
<li>there is overlap in the values that mean that <code>foo()</code> failed, <code>foo()</code> succeeded but the result is &quot;empty&quot;, or that the loop should end for ordinary reasons</li>
</ol>
<p>Maybe <code>foo()</code> reads from a device into a single, temporary buffer and returns the number of characters read, but also a value less than 0 if there's an error. So you can't just loop until <code>foo()</code>'s return value is no longer true-like. You also have to do this dance where you copy from the single-read buffer into the full-response buffer, reallocating or incrementing an offset pointer when necessary. You might also have to check to make sure that the buffer shared by <code>foo()</code> and <code>bar()</code> has valid contents, or cruft left over from last time, or uninitialised memory. And so on.</p>
<p>Once this pattern is established out of necessity eg. in stdlib functions, it becomes an idiom and is used even when alternatives are possible.</p>
<p>You can solve this at the language level by <strong>allowing users to access and manipulate types that represent data flow in loops</strong>. This is made more useful by having good &quot;optional&quot; types so that they have natural sentinel values for ending a loop, invalid values, etc.</p>
<p>Originally, I was going to suggest that the answer to this was something I use a lot in Rust: <a href="https://doc.rust-lang.org/std/iter/index.html" rel="noreferrer">iterators</a>. This is not original or unique to Rust, it's just the version I'm most familiar with. Python has a similar approach except with a special exception for ending an iterator.</p>
<p>An iterator <em>owns all the state required</em> to produce more values, and it has a <code>next()</code> method which returns <code>Some(item)</code> if there's another item, or <code>None</code> if there isn't. There are other semantics that are possible with more conditions, but that's the crux.</p>
<p>So you take apart your <code>foo()</code> and <code>bar()</code> functions and the underlying thing they manage, and put them in an iterator that &quot;owns&quot; the device or stream or whatever. Inside the <code>next()</code> method you do a single iteration of the read-check-buffer operations, and return <code>Some(data)</code> or <code>None</code>. The different concerns are neatly separated, plus there's support from the stdlib for eg. collecting all the readable data into a single buffer, or chaining subsequent operations.</p>
<p>Perhaps most crucially though: <em>the data returned from <code>next()</code> is available in the loop body if and only if the loop body executes.</em> So there is no confusion around &quot;does this buffer I put on the stack before starting the loop contain data from the last iteration? or invalid, uninitialised data?&quot; - no. If the loop body is running, if there is a value in the <code>item</code> binding, you're good. The operation to advance the loop worked. That's the data you got. If it failed, you won't be in the loop body.</p>
<p>As I said, originally I was going to cite &quot;iterators&quot; as a potential answer, but really it's just one realisation of what I said above: Rust (and Python) programmers now have access to the types that control data flow through loop iteration, because <code>for item in collection</code> is equivalent to turning <code>collection</code> into an iterator and looping until <code>None</code>s come out. Same with <code>while let</code>. (Rust also has an actual <a href="https://doc.rust-lang.org/std/ops/enum.ControlFlow.html" rel="noreferrer">control flow type</a> but the more common <code>Option</code> and <code>Result</code> also have elevated status in the language syntax and are more commonly used.)</p>

CC BY-SA 4.0
2023-07-02T06:31:32.870Z
2023-07-02T06:45:03.923Z
2023-07-02T06:45:03.923Z
detly
CC BY-SA 4.0
2023-07-03T13:50:26.777Z
You have the right idea, but the iterator protocol in Python doesn't care about `None`; it cares about either raising and handling a `StopIteration`, or explicitly counting values with a hidden integer value (used for indexing).
Karl Knechtel
CC BY-SA 4.0
2023-07-03T14:28:50.067Z
@KarlKnechtel I did mention that ("special exception"), albeit briefly. My point still stands. Python more or less _has_ to use an exception because there's no way to express the same kind of structure you might do with static types (eg. `Some(None)` or `Continue(())` being valid values), but it's still a realisation of letting the user dictate _both_ the loop control flow _and_ data flow coupled together.
detly
<p>This seems like a suitable use case for the do-while loop, which is supported in C.</p>
<pre><code>do
{
  foo();
}
while (condition &amp;&amp; bar());
</code></pre>

CC BY-SA 4.0
2023-07-01T14:43:36.363Z
2023-07-01T14:43:36.363Z
matt_rule
CC BY-SA 4.0
2023-07-01T16:19:06.470Z
This only works if `bar()` is an expression which always returns a truthy value. You can use `condition && (bar() || true)` to get around that if its value isn't necessarily truthy, but not when the part of the code represented by `bar();` is not an expression. For most use-cases the `bar();` part of the "loop-and-a-half" is considerably longer than the `foo();` part.
kaya3
<p>I saw this maybe 40 years ago in a book in a library, as a suggestion, not in an actual library. Normally we have loops with optional break statements. So the syntax for this loop was like:</p>
<pre><code>while (&lt;condition&gt;) until &lt;exit1&gt;, &lt;exit2&gt;, &lt;exit3&gt; {
    ....
    if (x &gt; 0) exit1;
    if (y &gt; 0) exit2;
    if (z &gt; 0) break;
    ...
    if (x == 0) exit3;
    ....
}
case case1: { statement; break; }
case case2: { statement; break; }
case case3: { statement; break; }
</code></pre>
<p>So after the loop condition comes &quot;until&quot; with one or more names for exit cases. The exit names can be used in your code just like break. And after the loop body it's like the cases of a switch statement. You can easily distinguish between &quot;break&quot; and the loop running to its end by using an exit name instead of break.</p>
<p>Of course this includes an n + 1/2 loop but is much more general.</p>

CC BY-SA 4.0
2023-07-03T14:18:58.273Z
2023-07-03T14:18:58.273Z
gnasher729
CC BY-SA 4.0
2023-08-04T20:46:56.443Z
Knuth included a version of this in _Literate Programming_, as I recall, but the version I remember didn't include the initial `while (<condition>)` clause, because the `if` statements can easily cover that clause:  The entire loop simply read as `until this, that, theOtherThing { ... }` and then `if` statements could exit it as needed.  (`until forever { ... }` reads nicely, too, for a loop that never ends.)
Sean Werkema
CC BY-SA 4.0
2023-07-03T14:24:29.663Z
This looks similar to [Roman Odaisky's existing answer](https://langdev.stackexchange.com/a/1881/15).
Bbrk24
<p>A possible syntax for Python-like (braceless, with syntactically-significant whitespace) languages, inspired by <a href="https://langdev.stackexchange.com/a/1816/189">Jeremy's answer</a>:</p>
<pre><code>while condition after:
    foo()
do:
    bar()
</code></pre>
<p>This introduces an additional <code>after</code> keyword (and probably also <code>do</code>; C-like languages commonly have that, but Python doesn't) to mark the construct explicitly. Assuming this cost is acceptable, I think this gets the best of all possible worlds otherwise:</p>
<ul>
<li><p>It's eminently readable: &quot;<code>while</code> this <code>condition</code> is met <code>after</code> doing this part, <code>do</code> that part&quot;.</p>
</li>
<li><p>The loop-controlling condition appears at the top, so it doesn't get lost in other code.</p>
</li>
<li><p>Both this sort of loop and an &quot;ordinary&quot; while loop start with the <code>while</code> keyword. For a longer loop, it's clear where control flow resumes at the end of the loop; the code reader won't accidentally ignore the preamble. The &quot;main&quot; part of the loop is no longer a valid loop by itself.</p>
</li>
<li><p>We get a do-while construction for free by simply omitting the <code>do:</code> block, and the reader can see the loop condition up front. <code>while False after:</code> tells us immediately that we have the equivalent of <code>do {} while (0)</code> without having to skip to the end. It's also less awkward with this style of syntax, since we can still follow the usual rule that a control-flow statement introduces a block.</p>
</li>
</ul>

CC BY-SA 4.0
2023-07-03T13:39:38.947Z
2023-07-03T13:39:38.947Z
Karl Knechtel
CC BY-SA 4.0
2023-07-03T13:43:15.627Z
I'll note that the only time I've seen `do { ... } while (false)` is in C/C++ macros, where it's useful to group multiple statements as if they're a single statement and require a semicolon at the end.
Bbrk24
CC BY-SA 4.0
2023-07-03T14:09:07.380Z
Admittedly I've never felt a compelling use for them in Python, but it does come for free here so I thought I'd point it out. The idea is that `break` can be used as a pseudo-goto to a common end point. Alternately, it gives some of the functionality of Javascript IIFEs.
Karl Knechtel
CC BY-SA 4.0
2023-07-03T14:16:23.530Z
The mian reason I've used IIFEs is to put multiple statements where a single expression is needed, e.g. in Swift `var button: UIButton = { let button = UIButton(); button.color = .blue; return button }()`. Making it out of do/while doesn't help with that.
Bbrk24
CC BY-SA 4.0
2023-07-03T14:23:07.677Z
It does if `break` is allowed to produce a value analogous to `return`, but that is admittedly a separate feature request :)
Karl Knechtel
CC BY-SA 4.0
2023-07-03T15:07:10.497Z
The more I think about it, the more I like this idea. The `after` bit could be a contextual keyword -- and therefore still allowed as an identifier -- if you require parentheses around the condition, as C does.
Bbrk24
<p>How about adding a keyword <code>entry</code>.  by re-ordering the loop top have the condition at the end and starting in the middle you get nce clean block with no internal branching.</p>
<pre><code>do{
    bar();
entry:
    foo();
}while (condition())
</code></pre>
<p>It's not immediatly clear that bar will be skipped initially, o perhaps a new keyword.</p>
<pre><code>do subsequently
{
     bar();
always: //  coulde be a different keyword like then or default: here instead
     foo();
} 
while ( condition() );
</code></pre>
<p><code>entry:</code> seems like a comefrom, and Intercal officianados excepted I don't think anyone prefers comefrom over goto, so probably cleaner to just use a goto.</p>
<pre><code>goto entry;
do{
    bar();
entry:
    foo();
}while (condition())
</code></pre>
<p>or rerhaps replace <code>do</code> with something that explicitly indicate that the loop starts in the middle. <code>do from entry</code> or something like that.</p>
<p>re-ordering the loop to put a middle test last is reminiscent of Duff's device, hence:</p>
<pre><code>switch (0)
{
     do
     {
          bar();
default:  foo();      
     } 
     while (condition());
}
</code></pre>
<p>not a seriouis suggestion obviously.</p>
<p>another possible language change could be to enhance <code>for(;;)</code>
with a &quot;glue&quot; slot  that is skipped on the first loop but othwerwise runs after the condition test.</p>
<pre><code> for(;condition();;bar())foo();
</code></pre>
<p>But <code>for(;;)</code> itself is already failrly complex, and thus can be hard to read,</p>
<p>Back to the original. ( here I'm using <code>for(;;)</code> instead of <code>while(1)</code> because it's idiomatic in C.  - substitute <code>while(1)</code> or <code>forever</code> etc if you prefer)</p>
<pre><code>for(;;)
{
    foo();
    if(condition()) break;
    bar();
}
</code></pre>
<p>This may actually be a good case for suffix-if</p>
<pre><code>for(;;)
{
    foo();
break if(condition());
    bar();
}
</code></pre>
<p>it shouldn't be too hard to teach a code formatter to <em>outdent</em> <code>break if</code></p>
<p>The outdented break makes the termination condition easy to find.  while the leading for{;;} makes it clear that you always get at-least one foo()</p>

CC BY-SA 4.0
2023-07-02T02:34:29.900Z
2023-07-04T00:34:36.740Z
2023-07-04T00:34:36.740Z
Jasen
CC BY-SA 4.0
2023-07-02T02:50:09.393Z
I don’t know of _any_ modern language that accepts that last one, and it’s an awful lot longer than the alternatives.
Bbrk24
CC BY-SA 4.0
2023-07-02T02:52:01.017Z
I didn't intend the last as a strong argument,  it's just an aside at how weird things can be.
Jasen
CC BY-SA 4.0
2023-07-02T03:11:14.383Z
duff's device seems odd. but I'm not language lawyer enough to say that it is forbidden.  compiles with no warnings and runs fine with `--std=c11`  what's "modern?"  what's C-family for that matter?
Jasen
CC BY-SA 4.0
2023-07-02T03:17:00.330Z
I don't tend to consider new editions of C/C++ "modern" because they still show their age in plenty of obvious ways.
Bbrk24
CC BY-SA 4.0
2023-07-02T13:51:43.983Z
I think the problem with this is that it puts the "bar" before the "foo", when logically "foo" happens before "bar". If the "foo" part stores something to a variable then the compiler needs to be able to tell that that variable is definitely initialised in the "bar" part; still possible by considering the control-flow graph, but it would look weird.
kaya3
CC BY-SA 4.0
2023-07-03T12:49:03.490Z
@Jasen: From an assembly-language programmer's PoV, the full Duff's Device is a way to shoehorn (into C) a computed jump (or jump-table lookup) to an entry point in an unrolled loop, instead of doing a separate prologue or epilogue for "cleanup" when the number of iterations isn't a multiple of the unroll factor.
Peter Cordes
CC BY-SA 4.0
2023-07-03T12:49:08.877Z
`switch(0) { ... default: ... }` is just a silly way to write a `goto`.  (To jump to the loop entry point, as a compiler might do in asm ([Why are loops always compiled into "do...while" style (tail jump)?](https://stackoverflow.com/q/47783926)) if it doesn't rotate and partially peel an iteration to put the condition at the bottom.)  In a language that supports `goto`, just write `goto` with a meaningful label name like `loop_entry`; it's the same bypassing of structured programming, obfuscating / disguising it as a `switch` doesn't make it better, except for scoping of the target.
Peter Cordes
CC BY-SA 4.0
2023-07-03T12:56:35.450Z
`entry:` as a keyword on its own (without a `goto`) seems like it could be hard to read in less trivial loops.  If it's not on screen when you're looking at the `do { ...` and first few lines of the top of the loop, you won't realize right away that the entry point isn't the top, unless there's a comment on or near the `do{` line, or some part of the language syntax indicates a special form of `do` which uses an entry-point label.  Like `do(entry) { ... entry: ... }` perhaps?  Having a choice of label name could let you jump into the middle of a nested `do{}while` for good or ill...
Peter Cordes
CC BY-SA 4.0
2023-07-03T13:52:10.260Z
This is an interesting exploration of options, but it hardly seems likely to make writing the code easier, more readable or less error-prone. (Also, OP already considered the simple `goto` approach.)
Karl Knechtel
CC BY-SA 4.0
2023-07-04T00:06:16.193Z
I'm averse to putting condition at the top because condition is not checked before running foo
Jasen
# How could a language make the loop-and-a-half less error-prone?
Posted by: username_0 on 2023-06-30
Anyone who's used C-family languages enough will have seen or used a "loop-and-a-half", which can be written in one of two ways:
foo();
while (condition) {
  bar();
  foo();
}

while (1) {
  foo();
  if (!condition) break;
  bar();
}

These examples show the basic structure of the "loop-and-a-half"; foo(); and bar(); here are placeholders for any statements. Often, the "foo" part reads some input, the "condition" checks that the input hasn't ended, and the "bar" part uses the input data somehow.
The former spelling involves code duplication, and the latter is error-prone (it's possible to forget the break statement and cause an infinite loop). It's possible to avoid both problems with a goto:
goto middle_of_loop;
while (condition) {
  bar();
middle_of_loop:
  foo();
}

but I've never seen this in practice, and newer languages tend not to have goto in the first place. Besides, goto has its own problems.
How could a C-family language make these easier to read and write? Does any language have a dedicated syntax for this?
**Tags:** c loops
> **Comments:**
> **username_1**: I've never really considered the second version to be error-prone. It concisely expresses the logic, and forgetting the break is simply a logic error.  
> **username_2**: Related: https://langdev.stackexchange.com/questions/95  
---
## 16 answers
### Answer by username_4 on 2023-06-30. Score: 23
Rust can achieve this without break or code duplication, since blocks are expressions:
while {
    foo();
    condition
} {
    bar();
}

Unfortunately this is a bit of an idiom, because the keyword while is separated from the actual condition for the loop; and the condition's location is marked by the } { line after it, which is weird. Perhaps if people get more used to the loop-and-a-half being written this way, it will become more intuitive.
Nonetheless it gets the job done, and the only language construct you need is block-expressions, i.e. a block delimited by braces which contains any number of statements followed by one expression, and the block's value is the value of the final expression.
> **Comments:**
> **username_0** (2023-07-01): I suppose you could achieve the same thing in, say, JS or Swift using an IIFE, but that gets a little punctuation-heavy, and it changes the semantics of `return` in a way that may not be desirable.  
> **username_9** (2023-07-01): `sh`, of all languages, also has this, just with a different spelling: `while foo; condition; do bar; done`.  
> **username_10** (2023-07-02): it splits the loop block into two which could be p a problem if you want to share a block scoped variable between the two parts.  
> **username_4** (2023-07-02): @Jasen That is a good point, but at least in Rust you can declare the variable outside of the loop, assign to it in the "foo" part, and Rust will know that it's definitely initialised when you use it in the "bar" part.  
> **username_11** (2023-07-02): I disagree that this is a good solution for this idiom. Firstly, it's a little surprising even to experienced users of Rust. Secondly, almost every time I've seen someone try this (from beginners on the Discord to colleagues at work), it's ended up with issues relating to ownership or aliasing, eg. `foo()` needs to own something that `bar()` needs later. And then you end up stuffing the output into an `Option` on the stack outside the loop, and presto, you've reinvented the `Option` based iterators but with less clarity and language support.  
> **username_4** (2023-07-02): @detly I didn't say it is a good solution; I said it "gets the job done" but is "unfortunately a bit of an idiom". Your point about ownership and lifetimes is largely addressed by my previous comment, but also not relevant unless you are designing the loop syntax for a language which has a Rust-like borrow checker (i.e. a tiny minority of languages).  
> **username_12** (2023-07-02): It's also very similar in Forth. `BEGIN foo condition WHILE bar REPEAT`  
---
### Answer by username_1 on 2023-06-30. Score: 19
In languages with a C-style comma operator, you can use
while (foo(), condition) {
    bar();
}
> **Comments:**
> **username_0** (2023-06-30): You’re not wrong, but as a matter of personal preference I think it’s ugly. Besides, this assumes that “foo()” is only a single expression, which isn’t always the case.  
> **username_6** (2023-07-01): @Bbrk24 No, it doesn't. You can have as many as you want with the comma operator. I agree it's not a particularly readable style though.  
> **username_0** (2023-07-01): @JackAidley They still need to be _expressions_ and not, say, nested loops.  
> **username_1** (2023-07-01): True, But Lampson's Law applies: you can move that loop into a function and call the function.  
> **username_13** (2023-07-01): This is pretty similar to the Rust approach described in kaya3's answer  
> **username_14** (2023-07-01): @Bbrk24 Nothing prevents you from designing loops as expressions. Also GNU C's [Statement Expressions](https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html).  
> **username_12** (2023-07-02): As we see in the other answers, other languages (as well as a GCC extension to the C language) solve this by allowing the condition to really contain multiple statements instead of using the comma operator hack.  
> **username_15** (2023-07-03): @Longinus: Nothing except readability!  Remember, we're looking for a usable idiom for real code that's easy to write and maintain overall, not *just* achieving the goal of not repeating `foo` or `bar`, or code-golf. (If code-golf was the goal, though, good point about statement-expressions allowing `{ anything }` to be an expression between commas if you structure it right).  If `foo()` is complex, a lambda with some captures is probably a good bet to make the pain of repeating it minimal, or to ease the readability of an idiom like this.  
> **username_14** (2023-07-03): @PeterCordes There is "real code that's easy to write and maintain overall" written in Zig, Clojure and F# that use looping expressions. Also many programmes use recursion as an iteration mechanism, which most of the time appears as self-referential expressions. Haskell also has libraries where the entire concept of a "loop" is generalised to various userland morphisms.  
> **username_16** (2023-07-04): Doesn't that allow the compiler to reorder foo() and condition in ways that were not allowed in the original?  Why not just use [C block expressions](https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html)?  
> **username_1** (2023-07-04): @MikeSamuel The comma operator guarantees to evaluate left to right. Block expressions are a GCC extension. Of course, if you're designing your own language you can add it.  
---
### Answer by username_2 on 2023-07-01. Score: 15
A frame challenge: the problem isn't really with the loop construct itself, but with ad-hoc bundling of the "half" loop with the condition check. This is a problem that should be solved elsewhere, mainly by the programmer but perhaps also by making (possibly anonymous) function syntax easier in the language.
Note that the problem disappears entirely, even in C, if the first half of the loop really is wrapped up in a foo function and that function returns the desired condition value; then we can simply write
while(foo()) bar();

In C (or C++), even if that doesn't hold up, we can exploit the comma operator - so, in this case:
while(foo(), condition) bar();

So really, problems occur because there isn't already a foo and there is some resistance to making it. My experience - across multiple programming languages and something like 35 years of writing code - has consistently been that the common case, by far, is that the foo logic has the explicit purpose of setting things up so that the loop condition can be evaluated, and that this process is coherent and nameable. As such, the resistance to creating a separate function usually just seems lazy to me. (Of course, there are language-specific idioms for one-off functions, like blocks and IIFEs (really popular in Javascript). But I think code clarity often suffers this way. Naming things is quite useful.)
Another thing that can help is to make it easier to work with generators and iterators. For example in Python, reading from a file produces an empty result if and only if we are at the end, which allows a clever idiom for reading a binary file in chunks.

As a footnote: even in the cases where we'd want to use the comma operator in C or C++, we might want to ask ourselves why the code is designed that way. In the linked answer, we suppose that we need the length of a string that is populated by an I/O function (granted this appears to be a C++ example on what was asked as a C question). Sure, it would be contrived (and inflexible) to have that function report whether the resulting string meets some specific condition, and perhaps awkward to make a wrapper. Even just having it report the length seems arbitrary (and makes it harder to give the function a good name).
But - it could simply return the string itself by reference, and then while(read_string(s), s.len() > 5) simply becomes while(read_string(s).len() > 5). Similarly in C: if we pass a pointer to a buffer, just return that pointer as well (or perhaps a more useful one inside the buffer). The standard library already works that way, after all. (Some languages, like Python, resist the idea of a function returning a value and also having side effects, for well-considered reasons. But then we might ask if we wouldn't be happier with a new object anyway. Incidentally, the new-since-3.8 walrus operator can enable some tricks comparable to what I showed with the comma operator.)
> **Comments:**
> **username_4** (2023-07-01): *"Note that the problem disappears entirely, even in C, if the first half of the loop really is wrapped up in a foo function and that function returns the desired condition value;"* ─ this isn't a practical solution to the problem, because usually the "foo" part of the loop-and-a-half declares some variable (e.g. `let line = input.readLine();`) which is used in the condition and also in the "bar" part. Factoring out the "foo" part into a separate function moves the variable `line` out of scope for the "bar" part.  
> **username_2** (2023-07-01): @kaya3-supportthestrike I could have sworn I originally planned to address that, but now I'm not really sure what to say about it. It definitely is a complication.  
> **username_17** (2023-07-01): @kaya3-supportthestrike One approach is to make a new object first so that `let line = input.readLine(); while (line) { bar(line); }` becomes `while (reader.readLine()) { bar(reader.line); }`  
> **username_18** (2023-07-02): Isn't the instantiation of a variable to be used for a loop, but declared outside the scope of a loop some sort of anti-pattern, as @krubo implies?  Isn't this entire question based upon anti-pattern semantics? cf. https://softwareengineering.stackexchange.com/questions/142144/whiletrue-and-loop-breaking-anti-pattern  
---
### Answer by username_3 on 2023-06-30. Score: 11
A least-change approach would be to make it a compiler error if you write a `while (true)` or `for (;;)` loop without a loop-exiting statement (`break`, `return`, or `throw`) somewhere inside it. This would solve the “forgetting the `break` statement” issue similarly to how C# dealt with C's error-prone fall-through between `case` blocks.

Perhaps some special syntax could be introduced for the case when you deliberately do want a loop to run “forever” (until the process is interrupted/terminated).
> **Comments:**
> **username_4** (2023-07-01): I think `throw` shouldn't be allowed as the only exit from such a loop, because other statements like `baz();` can also throw. If you have a separate "infinite loop without break" keyword like `forever` then `throw` could still be allowed in those loops though. This is just my opinion, but I think if you have separate keywords for the two kinds of loops then the distinction should be that `while` loops can complete normally (so the code after them is reachable) whereas `forever` loops can't complete normally (but can still complete abruptly by throwing).  
> **username_2** (2023-07-03): Good point. Designing new syntax (or citing other existing syntax examples) is interesting, but this answer focuses on the specific reason OP finds the original syntax error-prone.  
---
### Answer by username_5 on 2023-06-30. Score: 10
I've sometimes wished for a loop like
do {
  foo();
} while (condition) {
  bar();
}
> **Comments:**
> **username_6** (2023-07-01): That looks pretty readable to my eyes.  
> **username_2** (2023-07-01): I see this going really wrong when the `do` is off-screen reading a longer code example. The `while (condition) { bar(); }` part would be valid by itself, but now when control reaches that final `}`, it no longer goes to the "matching" `{`, but instead to the `do {` one. The `}` before `while` on the same line is a useful contextual clue, but that wouldn't apply in e.g. a language with Python-like braceless syntax.  
> **username_7** (2023-07-01): This seems elegant to implement. Instead of there being a separate `do {} while ()` construct, there can just be a `while ()` with an optional `do {}` prefix.  
> **username_8** (2023-07-03): I would be very confused if I saw this in code. Is `foo()` ran only once before the loop, and then `bar()` ran at every iteration? Or is `foo` ran at every iteration, and then `bar()` is ran only once after the loop?  
---
### Answer by username_11 on 2023-07-02. Score: 8
In my experience, this "half-loop" occurs for a couple of language-inherent reasons:

1. `foo()` needs to mutate some state related to the loop, usually in some fallible way, and `bar()` needs to non-fallibly get at *some* of the results; and
2. there is overlap in the values that mean that `foo()` failed, `foo()` succeeded but the result is "empty", or that the loop should end for ordinary reasons

Maybe `foo()` reads from a device into a single, temporary buffer and returns the number of characters read, but also a value less than 0 if there's an error. So you can't just loop until `foo()`'s return value is no longer true-like. You also have to do this dance where you copy from the single-read buffer into the full-response buffer, reallocating or incrementing an offset pointer when necessary. You might also have to check to make sure that the buffer shared by `foo()` and `bar()` has valid contents, or cruft left over from last time, or uninitialised memory. And so on.

Once this pattern is established out of necessity eg. in stdlib functions, it becomes an idiom and is used even when alternatives are possible.

You can solve this at the language level by **allowing users to access and manipulate types that represent data flow in loops**. This is made more useful by having good "optional" types so that they have natural sentinel values for ending a loop, invalid values, etc.

Originally, I was going to suggest that the answer to this was something I use a lot in Rust: [iterators](https://doc.rust-lang.org/std/iter/index.html). This is not original or unique to Rust, it's just the version I'm most familiar with. Python has a similar approach except with a special exception for ending an iterator.

An iterator *owns all the state required* to produce more values, and it has a `next()` method which returns `Some(item)` if there's another item, or `None` if there isn't. There are other semantics that are possible with more conditions, but that's the crux.

So you take apart your `foo()` and `bar()` functions and the underlying thing they manage, and put them in an iterator that "owns" the device or stream or whatever. Inside the `next()` method you do a single iteration of the read-check-buffer operations, and return `Some(data)` or `None`. The different concerns are neatly separated, plus there's support from the stdlib for eg. collecting all the readable data into a single buffer, or chaining subsequent operations.

Perhaps most crucially though: *the data returned from `next()` is available in the loop body if and only if the loop body executes.* So there is no confusion around "does this buffer I put on the stack before starting the loop contain data from the last iteration? or invalid, uninitialised data?" - no. If the loop body is running, if there is a value in the `item` binding, you're good. The operation to advance the loop worked. That's the data you got. If it failed, you won't be in the loop body.

As I said, originally I was going to cite "iterators" as a potential answer, but really it's just one realisation of what I said above: Rust (and Python) programmers now have access to the types that control data flow through loop iteration, because `for item in collection` is equivalent to turning `collection` into an iterator and looping until `None`s come out. Same with `while let`. (Rust also has an actual [control flow type](https://doc.rust-lang.org/std/ops/enum.ControlFlow.html) but the more common `Option` and `Result` also have elevated status in the language syntax and are more commonly used.)
> **Comments:**
> **username_2** (2023-07-03): You have the right idea, but the iterator protocol in Python doesn't care about `None`; it cares about either raising and handling a `StopIteration`, or explicitly counting values with a hidden integer value (used for indexing).  
> **username_11** (2023-07-03): @KarlKnechtel I did mention that ("special exception"), albeit briefly. My point still stands. Python more or less _has_ to use an exception because there's no way to express the same kind of structure you might do with static types (eg. `Some(None)` or `Continue(())` being valid values), but it's still a realisation of letting the user dictate _both_ the loop control flow _and_ data flow coupled together.  
---
### Answer by username_19 on 2023-07-02. Score: 7
Instead of having a separate condition expression, have the loop body return a Result, and repeat the loop until it's an error (i.e., "while it succeeds").
Using this style, you can rewrite all sorts of control flows by just changing where in the body the test is performed:
# Traditional `while`:
while {
    test_condition()?
    foo()
    bar()
}

# Loop-and-a-half:
while {
    foo()
    test_condition()?
    bar()
}

# Do-while
while {
    foo()
    bar()
    test_condition()?
}

Where fn()? is a Rust-style operator that immediately returns an error if the call fails. You can think of it as an assert, and the loop stops when the body fails an assertion.
With a little bit of optimizing, it should perform the same as a traditional while loop.
You can also extend it to boolean operators, where a false result is considered an error:
while {
    foo()
    (count < 10)? # or count 
This is better than the if (!condition) break because the condition can be used inline, and the user is less likely to forget the "break" since there's no obligatory condition at the start.

It can also replace other tricky scenarios, like an if that must operate on an assigned value only if it succeeds. This is a feature most languages need special syntax for, but happens naturally if the condition is part of the body:
if {
    match = re.match('\d+', str)?
    print("Got a number:", match)
} {
    match = re.match('[a-z]+', str)?
    print("Got a word:", match)
} {
    print("No match")
}
> **Comments:**
> **username_0** (2023-07-03): I don't know whether to be disgusted or amazed. As elegant as this looks in shorter code, it may be difficult to find the `?` in a longer loop, and this is even more error-prone / easy to forget than `break`. But sure, `Bool = Result<Void, Void>`, why not.  
> **username_19** (2023-07-03): @Bbrk24 Haha, that's a great reaction. I have a whole self-hosted language based on this trick, and so far it's been working really well, especially since you can interleave multiple condition tests as needed. But I totally understand the shock.  
> **username_20** (2023-07-04): I really like this concept, but I wonder that separating the condition from the 'while' impedes readability. Eg.: while { ... long procedure...  condition? ...more procedure... condition2? } - doesn't read very well. Perhaps renaming from "while" to "loop" or even "loop if" might reduce the disconnect between the syntax of the language and the syntax of English (assuming English). A potential advantage of "loop if" is you then have "loop for" in a matching style.  The "if" statement is less bad, but could still be confusing: if {condition1? condition2? foo()}. Is that condtion1 && condition2??  
---
### Answer by username_21 on 2023-07-02. Score: 6
If your only concern is someone missing a break, you could allow syntax like while(!break), while(!break && !throw) or whatever other loop-exiting mechanisms your language has. It would be equivalent to while(1) except it would be an error not to have the specified means of exiting the loop inside.
Also if your language has named breaks like in C. T. Zahn’s 1974 paper that I’m having trouble locating but that look like the following, perhaps you would be able to use that feature to require a break with a particular name.
for(item in items) {
    if(item.is_interesting()) {
        break found_interesting(item);
    }
    if(item.breaks_invariant()) {
        break epic_fail;
    }
}
when found_interesting(item) {
    do_something(item);
}
when epic_fail {
    crash();
}


Does any language have a dedicated syntax for this?

Forth:
BEGIN part1 WHILE part2 REPEAT

If part1 leaves a false value on the top of the stack, exit the loop. Nothing prevents part1 from doing a lot of other work prior to calculating whether to break.
> **Comments:**
> **username_0** (2023-07-02): Is [this](https://link.springer.com/chapter/10.1007/3-540-06859-7_133) the paper you're looking for?  
> **username_21** (2023-07-03): @Bbrk24 Yes, that’s the one. Looks very useful, I wonder why it hasn’t seen any adoption in 50 years.  
---
### Answer by username_22 on 2023-07-01. Score: 5
The following might be highly unidiomatic in many C-like languages, but you did ask "does any language have a dedicated syntax for this", which suggests that you might be looking for ideas from other families.
gcc does tail-call optimisation and C++ has lambdas, so I hope you grant that those are features a C-family language can have. With this in mind, F# would do the following:
let rec loop () =
    foo ()
    if condition then
        bar ()
        loop ()
loop ()

So what you want could plausibly be spelled as follows, where I've invented some syntax
nocapture void loop() {
    foo();
    if (condition) {
        bar();
        tail loop();
    }
}
loop();

I argue that this doesn't have code duplication (unless you count the initial invocation of the loop). I also argue that it's extremely clear what is going to happen when, such that "forgetting the condition" is a very unnatural move.
The downsides:

the mild one that it's eight lines rather than five;
the substantial one that depending on how the closure is implemented, an insufficiently smart compiler might copy local state to the heap, or it might become much more verbose as you have to specify what state is captured and where. The hypothetical language probably wants specific support for this pattern to make a user comfortable relying on it. (I gestured to this with nocapture and tail, but with an appropriate linter or a sufficiently smart compiler you wouldn't need those keywords.)

If you're designing a language which is happy to have a complicated spec anyway, then I'm sure you could special-case this pattern into the syntax to make it much shorter.
> **Comments:**
> **username_0** (2023-07-01): Now that you mention it, isn’t this how `loop`-`recur` works in Clojure? Having that as a macro or as a keyword pair could work just as well in a C-family language.  
---
### Answer by username_23 on 2023-07-02. Score: 4
Does any language have a dedicated syntax for this?

Bourne-shell type languages (sh, bash, zsh, etc.) have it:
while
  foo
  condition
do
  bar
done

To be clear, I'm answering on having a syntax that's specifically dedicated to this type of loop construct.
Other languages like Rust, Lisp-based languages, Ruby, Haskell, or even the same Bourne-shell based languages, will support very similar constructs by way of consequence from having a syntax that generically turns lists of statements into expressions. That enables their use in the loop condition, which is generally limited in most languages to an expression. In bash, that can look like this:
while {
  foo
  condition
}; do
  bar
done

Ruby:
while (foo; condition)
  bar
end

Haskell:
whileM (do { foo; condition }) $ do
  bar

Common Lisp:
(while (progn (foo) (condition))
  (bar))

JavaScript (not sure lambdas are fair, though):
while ((function () { foo; return condition; })()) {
  bar;
}

The while syntax in Bourne-shell type languages however, instead of taking a single command/expression for the condition, will take a list. From the bash manpage:

while list-1; do list-2; done
The while command continuously executes the list list-2 as long as the last command in the list list-1 returns an exit status of zero.

This is why it requires the do keyword to signify the end of one list and the start of the other.
I am aware that this doesn't show a significant functional difference if any for the language user. However, it is the only language I could think of that has a syntax dedicated to this as was asked, and I do think it's interesting to note, at least for this site, because having non-generic syntax rules like this does complicate the language. The idea of the return status of the last command being the return status of a list is not just documented where "lists" is documented, but also here where while is documented. And that has a sort of avalanche effect, because then set -e also has to make a special note on the lists used for while conditions, despite set -e not being about loops.

-e
Exit  immediately  if a pipeline (which may consist of a single simple command), a list, or  a  compound  command (see SHELL GRAMMAR above), exits with a non-zero status. The shell does not exit if the  command  that  fails  is part  of  the command list immediately following a while or until keyword
> **Comments:**
> **username_2** (2023-07-03): This seems to be essentially the same idea as in Rust (Kaya's answer).  
> **username_23** (2023-07-03): @KarlKnechtel I don't think so. The Rust one is following the idea that blocks of statements are expressions and their `while` syntax accepts an expression. Here, the `while` syntax specifically states it takes a "list": "list-2 is executed as long as the last command in list-1 returns a non-zero exit status" (bash manpage). This is why it has the `do` keyword to signify the end of list-1 and the start of list-2. If the syntax were instead to take a command (or pipeline) instead of a list, then it'd need either a `{}` or `()` compound command and I would agree with you that it's the same idea.  
---
### Answer by username_24 on 2023-07-03. Score: 4
In some languages, like Dart for example, assignments also return the value. While it's not applicable to all situations, it removes the necessity of a loop-and-a-half in some cases. For example you could write this while loop
String? input = stdin.readLineSync()
while (input != "end") {
    print(input);
    input = stdin.readLineSync()
}

as this instead
String? input;
while ((input = stdin.readLineSync()) != "end") {
    print(input);
}
---
### Answer by username_25 on 2023-07-02. Score: 4
Directly as
loop
   foo;
   exit when not condition;
   bar;
end loop;

in either Ada or VHDL for example.
> **Comments:**
> **username_26** (2023-07-02): That's what I would have suggested, except that you beat me to it, and I would have recommended outdenting the "exit when" line to match up with "loop" and "end-loop" when there aren't any nested control structures.  Perhaps I might also add a syntactic marker that would be required before any statement which contained a statement that would exit the loop, with a recommendation that such a marker be aligned with the start and end of the loop.  
> **username_2** (2023-07-03): It's not clear to me what `exit when not condition` is really doing better (= in a less error-prone way) than `if (!condition) break`.  
> **username_25** (2023-07-03): @KarlKnechtel mainly that this is what `exit` is for; `break` in C has other uses. So in a trivial example, I'd agree both are equally error-resistant, but more complex code with nested if and case statements / switches can become challenging. Both Ada, VHDL of course still have `while` and `for` loops, which are just syntactic sugar over this basic loop. (VHDL allows labelling loops, and `exit <label> when ...` for nested loops)  
---
### Answer by username_10 on 2023-07-02. Score: 3
How about adding a keyword entry.  by re-ordering the loop top have the condition at the end and starting in the middle you get nce clean block with no internal branching.
do{
    bar();
entry:
    foo();
}while (condition())

It's not immediatly clear that bar will be skipped initially, o perhaps a new keyword.
do subsequently
{
     bar();
always: //  coulde be a different keyword like then or default: here instead
     foo();
} 
while ( condition() );

entry: seems like a comefrom, and Intercal officianados excepted I don't think anyone prefers comefrom over goto, so probably cleaner to just use a goto.
goto entry;
do{
    bar();
entry:
    foo();
}while (condition())

or rerhaps replace do with something that explicitly indicate that the loop starts in the middle. do from entry or something like that.
re-ordering the loop to put a middle test last is reminiscent of Duff's device, hence:
switch (0)
{
     do
     {
          bar();
default:  foo();      
     } 
     while (condition());
}

not a seriouis suggestion obviously.
another possible language change could be to enhance for(;;)
with a "glue" slot  that is skipped on the first loop but othwerwise runs after the condition test.
 for(;condition();;bar())foo();

But for(;;) itself is already failrly complex, and thus can be hard to read,
Back to the original. ( here I'm using for(;;) instead of while(1) because it's idiomatic in C.  - substitute while(1) or forever etc if you prefer)
for(;;)
{
    foo();
    if(condition()) break;
    bar();
}

This may actually be a good case for suffix-if
for(;;)
{
    foo();
break if(condition());
    bar();
}

it shouldn't be too hard to teach a code formatter to outdent break if
The outdented break makes the termination condition easy to find.  while the leading for{;;} makes it clear that you always get at-least one foo()
> **Comments:**
> **username_0** (2023-07-02): I don’t know of _any_ modern language that accepts that last one, and it’s an awful lot longer than the alternatives.  
> **username_10** (2023-07-02): I didn't intend the last as a strong argument,  it's just an aside at how weird things can be.  
> **username_10** (2023-07-02): duff's device seems odd. but I'm not language lawyer enough to say that it is forbidden.  compiles with no warnings and runs fine with `--std=c11`  what's "modern?"  what's C-family for that matter?  
> **username_0** (2023-07-02): I don't tend to consider new editions of C/C++ "modern" because they still show their age in plenty of obvious ways.  
> **username_4** (2023-07-02): I think the problem with this is that it puts the "bar" before the "foo", when logically "foo" happens before "bar". If the "foo" part stores something to a variable then the compiler needs to be able to tell that that variable is definitely initialised in the "bar" part; still possible by considering the control-flow graph, but it would look weird.  
> **username_15** (2023-07-03): @Jasen: From an assembly-language programmer's PoV, the full Duff's Device is a way to shoehorn (into C) a computed jump (or jump-table lookup) to an entry point in an unrolled loop, instead of doing a separate prologue or epilogue for "cleanup" when the number of iterations isn't a multiple of the unroll factor.  
> **username_15** (2023-07-03): `switch(0) { ... default: ... }` is just a silly way to write a `goto`.  (To jump to the loop entry point, as a compiler might do in asm ([Why are loops always compiled into "do...while" style (tail jump)?](https://stackoverflow.com/q/47783926)) if it doesn't rotate and partially peel an iteration to put the condition at the bottom.)  In a language that supports `goto`, just write `goto` with a meaningful label name like `loop_entry`; it's the same bypassing of structured programming, obfuscating / disguising it as a `switch` doesn't make it better, except for scoping of the target.  
> **username_15** (2023-07-03): `entry:` as a keyword on its own (without a `goto`) seems like it could be hard to read in less trivial loops.  If it's not on screen when you're looking at the `do { ...` and first few lines of the top of the loop, you won't realize right away that the entry point isn't the top, unless there's a comment on or near the `do{` line, or some part of the language syntax indicates a special form of `do` which uses an entry-point label.  Like `do(entry) { ... entry: ... }` perhaps?  Having a choice of label name could let you jump into the middle of a nested `do{}while` for good or ill...  
> **username_2** (2023-07-03): This is an interesting exploration of options, but it hardly seems likely to make writing the code easier, more readable or less error-prone. (Also, OP already considered the simple `goto` approach.)  
> **username_10** (2023-07-04): I'm averse to putting condition at the top because condition is not checked before running foo  
---
### Answer by username_27 on 2023-07-01. Score: 2
This seems like a suitable use case for the do-while loop, which is supported in C.
do
{
  foo();
}
while (condition && bar());
> **Comments:**
> **username_4** (2023-07-01): This only works if `bar()` is an expression which always returns a truthy value. You can use `condition && (bar() || true)` to get around that if its value isn't necessarily truthy, but not when the part of the code represented by `bar();` is not an expression. For most use-cases the `bar();` part of the "loop-and-a-half" is considerably longer than the `foo();` part.  
---
### Answer by username_28 on 2023-07-03. Score: 2
I saw this maybe 40 years ago in a book in a library, as a suggestion, not in an actual library. Normally we have loops with optional break statements. So the syntax for this loop was like:
while () until , ,  {
    ....
    if (x > 0) exit1;
    if (y > 0) exit2;
    if (z > 0) break;
    ...
    if (x == 0) exit3;
    ....
}
case case1: { statement; break; }
case case2: { statement; break; }
case case3: { statement; break; }

So after the loop condition comes "until" with one or more names for exit cases. The exit names can be used in your code just like break. And after the loop body it's like the cases of a switch statement. You can easily distinguish between "break" and the loop running to its end by using an exit name instead of break.
Of course this includes an n + 1/2 loop but is much more general.
> **Comments:**
> **username_0** (2023-07-03): This looks similar to [Roman Odaisky's existing answer](https://langdev.stackexchange.com/a/1881/15).  
> **username_29** (2023-08-04): Knuth included a version of this in _Literate Programming_, as I recall, but the version I remember didn't include the initial `while (<condition>)` clause, because the `if` statements can easily cover that clause:  The entire loop simply read as `until this, that, theOtherThing { ... }` and then `if` statements could exit it as needed.  (`until forever { ... }` reads nicely, too, for a loop that never ends.)  
---
### Answer by username_2 on 2023-07-03. Score: 2
A possible syntax for Python-like (braceless, with syntactically-significant whitespace) languages, inspired by Jeremy's answer:
while condition after:
    foo()
do:
    bar()

This introduces an additional after keyword (and probably also do; C-like languages commonly have that, but Python doesn't) to mark the construct explicitly. Assuming this cost is acceptable, I think this gets the best of all possible worlds otherwise:

It's eminently readable: "while this condition is met after doing this part, do that part".

The loop-controlling condition appears at the top, so it doesn't get lost in other code.

Both this sort of loop and an "ordinary" while loop start with the while keyword. For a longer loop, it's clear where control flow resumes at the end of the loop; the code reader won't accidentally ignore the preamble. The "main" part of the loop is no longer a valid loop by itself.

We get a do-while construction for free by simply omitting the do: block, and the reader can see the loop condition up front. while False after: tells us immediately that we have the equivalent of do {} while (0) without having to skip to the end. It's also less awkward with this style of syntax, since we can still follow the usual rule that a control-flow statement introduces a block.
> **Comments:**
> **username_0** (2023-07-03): I'll note that the only time I've seen `do { ... } while (false)` is in C/C++ macros, where it's useful to group multiple statements as if they're a single statement and require a semicolon at the end.  
> **username_2** (2023-07-03): Admittedly I've never felt a compelling use for them in Python, but it does come for free here so I thought I'd point it out. The idea is that `break` can be used as a pseudo-goto to a common end point. Alternately, it gives some of the functionality of Javascript IIFEs.  
> **username_0** (2023-07-03): The mian reason I've used IIFEs is to put multiple statements where a single expression is needed, e.g. in Swift `var button: UIButton = { let button = UIButton(); button.color = .blue; return button }()`. Making it out of do/while doesn't help with that.  
> **username_2** (2023-07-03): It does if `break` is allowed to produce a value analogous to `return`, but that is admittedly a separate feature request :)  
> **username_0** (2023-07-03): The more I think about it, the more I like this idea. The `after` bit could be a contextual keyword -- and therefore still allowed as an identifier -- if you require parentheses around the condition, as C does.  
---
