<p>I've noticed that many template engines have a mechanism for detecting that a loop is not occurring.</p>
<p>Although their names and syntax vary, they all have this similar structure.</p>
<p>For example:</p>
<ul>
<li>Jinja</li>
</ul>
<pre><code>{% for user in users %}
    {{ user }}
{% else %}
    This is only evaluated if `users` is empty
{% endfor %}
</code></pre>
<ul>
<li>Jade</li>
</ul>
<pre><code>- var users = [];
ul
  each user in users 
    li= val
  else
    li This is only evaluated if `users` is empty
</code></pre>
<ul>
<li>Hugo</li>
</ul>
<pre><code>{{ range $users }}
    {{ . }}
{{ else }}
    This is only evaluated if $users is empty
{{ end }}
</code></pre>
<p>But I have hardly seen similar constructs in general-purpose programming languages.</p>
<p><sub><strong>Notice:</strong> <em>Python does not have this structure, these languages implement <code>no-run</code> detection, while python implements <code>no-break</code> detection.</em></sub></p>
<p>What causes the disagreement between template language authors and general-purpose language authors?</p>

<syntax><syntactic-sugar><template-languages>
Why do many template languages have `for-else` statements?
CC BY-SA 4.0
2023-11-10T07:15:49.483Z
To process zero items, there is nothing to do. But to display zero items, you often need to display something friendly like "No item found".
Eldritch Conundrum
<p>For exactly the same reason that most imperative programming languages that do iteration with for loops accept an empty collection to iterate over instead of throwing an error. It’s a very common case to need to account for, and it also is much easier to read if you don’t need the check for an empty collection.</p>
<p>Similarly, the general construct you show in your examples of doing something different if a collection of items is empty is a very common need when doing presentational templating (which accounts for a vast majority of template language usage), and it’s much easier to read a for/else syntax than it is to read an if/for/else construct.</p>
<p>Using Jinja as a point of comparison, here’s what that example would look like without for/else syntax:</p>
<pre><code>{% if users|length &gt; 0 %}
    {% for user in users %}
        {{ user }}
    {% endfor %}
{% else %}
    This is only evaluated if `users` is empty
{% endif %}
</code></pre>
<p>It’s not <em>horrible</em>, but there’s a lot more template language in there than in the for/else case, which is less than ideal especially given that this type of thing is likely to show up very frequently if you’re rendering things that users will be seeing.</p>

CC BY-SA 4.0
2023-11-11T13:06:06.627Z
2023-11-11T18:18:08.823Z
2023-11-11T18:18:08.823Z
Austin Hemmelgarn
<p>I believe this is because general purpose PLs have been conservative, especially around syntax and reserved words, and they had no chance to absorb these highly useful ideas from template languages, which are newcomers to this landscape and prioritize convenience over tradition.</p>
<p>C had three-section <code>for</code> loop which influenced a lot of languages and which allowed for fine tuning of looping conditions, which almost nobody used.</p>
<p>Java used &quot;smart for-loop&quot; which Steve Yegge <a href="https://sites.google.com/site/steveyegge2/next-big-thing" rel="nofollow noreferrer">called &quot;dumb for-loop&quot;</a> because you could do even less things with it than with traditional for-loop. Unfortunately, it did not catch further, and now you have better chances of seeing functional programming / Java streams / LINQ rather than any innovative structured programming constructs.</p>
<p>If you would be designing a programming language from scratch, <em>of course</em> you will have a way to iterate a collection, and it will have the ability to</p>
<ul>
<li>Determine whether current item is first/last item being iterated.</li>
<li>Remove current item from collection being iterated.</li>
<li>Run an auxiliary code block when the collection was empty (that's what this question is about).</li>
</ul>
<p>I'm placing some hopes on Kotlin which has rich syntax already.</p>

CC BY-SA 4.0
2023-11-10T15:14:41.197Z
2023-11-10T21:21:05.020Z
2023-11-10T21:21:05.020Z
alamar
CC BY-SA 4.0
2023-11-10T17:29:21.877Z
Sorry, what is a PLA?
kaya3
CC BY-SA 4.0
2023-11-10T18:22:35.300Z
I'd say C's "for" loop is designed more to save vertical space than to allow "fine tuning".  A loop design intended to facilitate fine tuning would specify that omitting the second clause would cause the first pass to be executed unconditionally, and repeat until evaluation of the third clause yielded zero.
supercat
CC BY-SA 4.0
2023-11-10T23:24:19.413Z
There are two common "for"-loop idioms in C (indexed loop, such as over an array, and until-null loop, such as over a list).  The three-section loop syntax permits expressing both idioms with the same keyword (`for(i = 0; i < 10; i++)` and `for(p = head; p != NULL; p = p->next)`).
Mark
CC BY-SA 4.0
2023-11-11T04:56:20.367Z
I like this idea. I want to add a `loop` context keyword to detect the beginning and end of the loop and the number of loops. With static analysis, only the required flags will be recorded, this is zero overhead. but the problem is that multiple loops will have conflict.
Aster
CC BY-SA 4.0
2023-11-11T06:41:52.710Z
@Aster See how Kotlin does that, the syntax would be `loop@Label ...;`
alamar
CC BY-SA 4.0
2023-11-12T17:09:20.600Z
“because you could do even less things with it than with traditional for-loop.” The same can be said about goto: you can do less things with while than with goto, yet almost nobody argues about which is better
Seggan
CC BY-SA 4.0
2023-11-12T23:56:44.340Z
@Mark Also `for (p = some_string; *p != '\0'; ++p)`
Stef
<h3>Poor composition</h3>
<p>Template languages tend to be less complex, and by so, care less for composition problems.</p>
<p>But a <code>else</code> clause in <code>loop</code>s compose baldy with <code>if</code>s:</p>
<pre><code>if cond
each user in users 
  { ... }
else
  { ... } // of each, possibly empty, to guarantee that
else
  { ... } // this else, of if, is reachable.
</code></pre>
<p>On languages with named end delimitador this is a lesser problem (the Jinja example).</p>
<p>But in languages with with fixed or implied block end delimitation, this may cause a variation of <a href="https://en.wikipedia.org/wiki/Dangling_else" rel="nofollow noreferrer">dangling else</a> problem.</p>

CC BY-SA 4.0
2023-11-10T12:33:43.870Z
2023-11-10T12:33:43.870Z
André L F S Bacci
CC BY-SA 4.0
2023-11-10T14:28:43.543Z
This answer seems more like a critique of the design principle in general rather than an explanation why so many languages choose to use it regardless. "Because the designers were stupid" would not be a satisfying answer. You should at least try to explain what thought patterns lead to this design.
Philipp
CC BY-SA 4.0
2023-11-10T17:32:53.117Z
This problem isn't specific to using "else" for an empty collection ─ it also occurs with nested if statements, e.g. `if(A) if(B) C else D` ─ and in any case it goes away if this ambiguity in the grammar is fixed (e.g. by requiring braces). It also applies to `for`/`else` with other semantics, such as in Python where the `else` clause executes when the loop completes without `break`ing. So this answer isn't very responsive to the question, because it focuses on just the syntax of the feature.
kaya3
<p>Template languages tend to format a document to show to a human, when doing a foreach on a set you are likely outputting a list of results.</p>
<p>It is good UX to have a explicit message when there are no results to show rather than to show nothing (which can look like a bug).</p>
<p>So there is high demand for a default handling of the zero count loop,</p>
<p>Whereas in imperative languages doing a loop means accumulating a result. An empty set will result in the initial value of the accumulator. You need that initial value anyway to initialize it and that starting value is often good enough as the result.</p>

CC BY-SA 4.0
2023-11-10T11:56:20.770Z
2023-11-10T11:56:20.770Z
ratchet freak
# Why do many template languages have `for-else` statements?
Posted by: username_0 on 2023-11-10
I've noticed that many template engines have a mechanism for detecting that a loop is not occurring.
Although their names and syntax vary, they all have this similar structure.
For example:

Jinja

{% for user in users %}
    {{ user }}
{% else %}
    This is only evaluated if `users` is empty
{% endfor %}


Jade

- var users = [];
ul
  each user in users 
    li= val
  else
    li This is only evaluated if `users` is empty


Hugo

{{ range $users }}
    {{ . }}
{{ else }}
    This is only evaluated if $users is empty
{{ end }}

But I have hardly seen similar constructs in general-purpose programming languages.
Notice: Python does not have this structure, these languages implement no-run detection, while python implements no-break detection.
What causes the disagreement between template language authors and general-purpose language authors?
**Tags:** syntax syntactic-sugar template-languages
> **Comments:**
> **username_1**: To process zero items, there is nothing to do. But to display zero items, you often need to display something friendly like "No item found".  
---
## 4 answers
### Answer by username_11 on 2023-11-10. Score: 44 | Accepted answer
Template languages tend to format a document to show to a human, when doing a foreach on a set you are likely outputting a list of results.

It is good UX to have a explicit message when there are no results to show rather than to show nothing (which can look like a bug).

So there is high demand for a default handling of the zero count loop,

Whereas in imperative languages doing a loop means accumulating a result. An empty set will result in the initial value of the accumulator. You need that initial value anyway to initialize it and that starting value is often good enough as the result.
---
### Answer by username_2 on 2023-11-11. Score: 5
For exactly the same reason that most imperative programming languages that do iteration with for loops accept an empty collection to iterate over instead of throwing an error. It’s a very common case to need to account for, and it also is much easier to read if you don’t need the check for an empty collection.
Similarly, the general construct you show in your examples of doing something different if a collection of items is empty is a very common need when doing presentational templating (which accounts for a vast majority of template language usage), and it’s much easier to read a for/else syntax than it is to read an if/for/else construct.
Using Jinja as a point of comparison, here’s what that example would look like without for/else syntax:
{% if users|length > 0 %}
    {% for user in users %}
        {{ user }}
    {% endfor %}
{% else %}
    This is only evaluated if `users` is empty
{% endif %}

It’s not horrible, but there’s a lot more template language in there than in the for/else case, which is less than ideal especially given that this type of thing is likely to show up very frequently if you’re rendering things that users will be seeing.
---
### Answer by username_3 on 2023-11-10. Score: 2
I believe this is because general purpose PLs have been conservative, especially around syntax and reserved words, and they had no chance to absorb these highly useful ideas from template languages, which are newcomers to this landscape and prioritize convenience over tradition.

C had three-section `for` loop which influenced a lot of languages and which allowed for fine tuning of looping conditions, which almost nobody used.

Java used "smart for-loop" which Steve Yegge [called "dumb for-loop"](https://sites.google.com/site/steveyegge2/next-big-thing) because you could do even less things with it than with traditional for-loop. Unfortunately, it did not catch further, and now you have better chances of seeing functional programming / Java streams / LINQ rather than any innovative structured programming constructs.

If you would be designing a programming language from scratch, *of course* you will have a way to iterate a collection, and it will have the ability to

* Determine whether current item is first/last item being iterated.
* Remove current item from collection being iterated.
* Run an auxiliary code block when the collection was empty (that's what this question is about).

I'm placing some hopes on Kotlin which has rich syntax already.
> **Comments:**
> **username_4** (2023-11-10): Sorry, what is a PLA?  
> **username_5** (2023-11-10): I'd say C's "for" loop is designed more to save vertical space than to allow "fine tuning".  A loop design intended to facilitate fine tuning would specify that omitting the second clause would cause the first pass to be executed unconditionally, and repeat until evaluation of the third clause yielded zero.  
> **username_6** (2023-11-10): There are two common "for"-loop idioms in C (indexed loop, such as over an array, and until-null loop, such as over a list).  The three-section loop syntax permits expressing both idioms with the same keyword (`for(i = 0; i < 10; i++)` and `for(p = head; p != NULL; p = p->next)`).  
> **username_0** (2023-11-11): I like this idea. I want to add a `loop` context keyword to detect the beginning and end of the loop and the number of loops. With static analysis, only the required flags will be recorded, this is zero overhead. but the problem is that multiple loops will have conflict.  
> **username_3** (2023-11-11): @Aster See how Kotlin does that, the syntax would be `loop@Label ...;`  
> **username_7** (2023-11-12): “because you could do even less things with it than with traditional for-loop.” The same can be said about goto: you can do less things with while than with goto, yet almost nobody argues about which is better  
> **username_8** (2023-11-12): @Mark Also `for (p = some_string; *p != '\0'; ++p)`  
---
### Answer by username_9 on 2023-11-10. Score: -3
Poor composition
Template languages tend to be less complex, and by so, care less for composition problems.
But a else clause in loops compose baldy with ifs:
if cond
each user in users 
  { ... }
else
  { ... } // of each, possibly empty, to guarantee that
else
  { ... } // this else, of if, is reachable.

On languages with named end delimitador this is a lesser problem (the Jinja example).
But in languages with with fixed or implied block end delimitation, this may cause a variation of dangling else problem.
> **Comments:**
> **username_10** (2023-11-10): This answer seems more like a critique of the design principle in general rather than an explanation why so many languages choose to use it regardless. "Because the designers were stupid" would not be a satisfying answer. You should at least try to explain what thought patterns lead to this design.  
> **username_4** (2023-11-10): This problem isn't specific to using "else" for an empty collection ─ it also occurs with nested if statements, e.g. `if(A) if(B) C else D` ─ and in any case it goes away if this ambiguity in the grammar is fixed (e.g. by requiring braces). It also applies to `for`/`else` with other semantics, such as in Python where the `else` clause executes when the loop completes without `break`ing. So this answer isn't very responsive to the question, because it focuses on just the syntax of the feature.  
---
