While it may be tempting to use loops if you're familiar with them in other languages, it is considered more in the [Nushell-style](book/thinking_in_nu.html) (idiomatic) to use commands that apply closures when you can solve a problem either way. The reason for this is because of a pretty big downside with using loops.
#### Loop Disadvantages
The biggest downside of loops is that they are statements, unlike [`each`](/commands/docs/each.html) which is an expression. Expressions, like [`each`](/commands/docs/each.html) always result in some output value, however statements do not.
This means that they don't work well with immutable variables and using immutable variables is considered a more [Nushell-style](/book/thinking_in_nu.html#variables-are-immutable). Without a mutable variable declared beforehand in the example in the previous section, it would be impossible to use [`for`](/commands/docs/each.html) to get the list of numbers with incremented numbers, or any value at all.
Statements also don't work in Nushell pipelines which require some output. In fact Nushell will give an error if you try:
```nu
[1 2 3] | for x in $in { $x + 1 } | $in ++ [5 6 7]
# => Error: nu::parser::unexpected_keyword
# =>
# => × Statement used in pipeline.
# => ╭─[entry #5:1:1]
# => 1 │ [1 2 3] | for x in $in { $x + 1 } | $in ++ [5 6 7]
# => · ─┬─
# => · ╰── not allowed in pipeline
# => ╰────
# => help: 'for' keyword is not allowed in pipeline. Use 'for' by itself, outside of a pipeline.
```
Because Nushell is very pipeline oriented, this means using expression commands like [`each`](/commands/docs/each.html) is typically more natural than loop statements.
#### Loop Advantages
If loops have such a big disadvantage, why do they exist? Well, one reason is that closures, like [`each`](/commands/docs/each.html) uses, can't modify mutable variables in the surrounding environment. If you try to modify a mutable variable in a closure you will get an error:
```nu
mut foo = []
[1 2 3] | each { $foo = ($foo | append ($in + 1)) }
# => Error: nu::parser::expected_keyword
# =>
# => × Capture of mutable variable.
# => ╭─[entry #8:1:1]
# => 1 │ [1 2 3] | each { $foo = ($foo | append ($in + 1)) }
# => · ──┬─
# => · ╰── capture of mutable variable
# => ╰────
```
If you modify an environmental variable in a closure, you can, but it will only modify it within the scope of the closure, leaving it unchanged everywhere else. Loops, however, use [blocks](/book/types_of_data.html#blocks) which means they can modify a regular mutable variable or an environmental variable within the larger scope.
```nu
mut result = []
for $it in [1 2 3] { $result = ($result | append ($it + 1)) }
$result
# => ╭───┬───╮
# => │ 0 │ 2 │
# => │ 1 │ 3 │
# => │ 2 │ 4 │
# => ╰───┴───╯
```
### `for`
[`for`](/commands/docs/for.html) loops over a range or collection like a list or a table.
```nu
for x in [1 2 3] { $x * $x | print }
# => 1
# => 4
# => 9
```
#### Expression Command Alternatives
- [`each`](/commands/docs/each.html)
- [`par-each`](/commands/docs/par-each.html)
- [`where`](/commands/docs/where.html)/[`filter`](/commands/docs/filter.html)
- [`reduce`](/commands/docs/reduce.html)
### `while`
[`while`](/commands/docs/while.html) loops the same block of code until the given condition is `false`.
```nu
mut x = 0; while $x < 10 { $x = $x + 1 }; $x
# => 10
```
#### Expression Command Alternatives
The "until" and other "while" commands
- [`take until`](/commands/docs/take_until.html)
- [`take while`](/commands/docs/take_while.html)
- [`skip until`](/commands/docs/skip_until.html)
- [`skip while`](/commands/docs/skip_while.html)
### `loop`
[`loop`](/commands/docs/loop.html) loops a block infinitely. You can use [`break`](/commands/docs/break.html) (as described in the next section) to limit how many times it loops. It can also be handy for continuously running scripts, like an interactive prompt.