# Loop Constructs in Move

Many programs require iteration over values, and Move provides `while`

and `loop`

forms to allow you
to write code in these situations. In addition, you can also modify control flow of these loops
during execution by using `break`

(to exit the loop) and `continue`

(to skip the remainder of this
iteration and return to the top of the control flow structure).

`while`

Loops

The `while`

construct repeats the body (an expression of type unit) until the condition (an
expression of type `bool`

) evaluates to `false`

.

Here is an example of simple `while`

loop that computes the sum of the numbers from `1`

to `n`

:

```
fun sum(n: u64): u64 {
let mut sum = 0;
let mut i = 1;
while (i <= n) {
sum = sum + i;
i = i + 1
};
sum
}
```

Infinite `while`

loops are also allowed:

```
fun foo() {
while (true) { }
}
```

### Using `break`

Inside of `while`

Loops

In Move, `while`

loops can use `break`

to exit early. For example, suppose we were looking for the
position of a value in a vector, and would like to `break`

if we find it:

```
fun find_position(values: &vector<u64>, target_value: u64): Option<u64> {
let size = vector::length(values);
let mut i = 0;
let mut found = false;
while (i < size) {
if (vector::borrow(values, i) == &target_value) {
found = true;
break
};
i = i + 1
};
if (found) {
Option::Some(i)
} else {
Option::None
}
}
```

Here, if the borrowed vector value is equal to our target value, we set the `found`

flag to `true`

and then call `break`

, which will cause the program to exit the loop.

Finally, note that `break`

for `while`

loops cannot take a value: `while`

loops always return the
unit type `()`

and thus `break`

does, too.

### Using `continue`

Inside of `while`

Loops

Similar to `break`

, Move's `while`

loops can invoke `continue`

to skip over part of the loop body.
This allows us to skip part of a computation if a condition is not met, such as in the following
example:

```
fun sum_even(values: &vector<u64>): u64 {
let size = vector::length(values);
let mut i = 0;
let mut even_sum = 0;
while (i < size) {
let number = *vector::borrow(values, i);
i = i + 1;
if (number % 2 == 1) continue;
even_sum = even_sum + number;
};
even_sum
}
```

This code will iterate over the provided vector. For each entry, if that entry is an even number, it
will add it to the `even_sum`

. If it is not, however, it will call `continue`

, skipping the sum
operation and returning to the `while`

loop conditional check.

`loop`

Expressions

The `loop`

expression repeats the loop body (an expression with type `()`

) until it hits a `break`

:

```
fun sum(n: u64): u64 {
let mut sum = 0;
let mut i = 1;
loop {
i = i + 1;
if (i >= n) break;
sum = sum + i;
};
sum
}
```

Without a `break`

, the loop will continue forever. In the example below, the program will run
forever because the `loop`

does not have a `break`

:

```
fun foo() {
let mut i = 0;
loop { i = i + 1 }
}
```

Here is an example that uses `loop`

to write the `sum`

function:

```
fun sum(n: u64): u64 {
let sum = 0;
let i = 0;
loop {
i = i + 1;
if (i > n) break;
sum = sum + i
};
sum
}
```

### Using `break`

with Values in `loop`

Unlike `while`

loops, which always return `()`

, a `loop`

may return a value using `break`

. In doing
so, the overall `loop`

expression evaluates to a value of that type. For example, we can rewrite
`find_position`

from above using `loop`

and `break`

, immediately returning the index if we find it:

```
fun find_position(values: &vector<u64>, target_value: u64): Option<u64> {
let size = vector::length(values);
let mut i = 0;
loop {
if (vector::borrow(values, i) == &target_value) {
break Option::Some(i)
} else if (i >= size) {
break Option::None
};
i = i + 1;
}
}
```

This loop will break with an option result, and, as the last expression in the function body, will produce that value as the final function result.

### Using `continue`

Inside of `loop`

Expressions

As you might expect, `continue`

can also be used inside a `loop`

. Here is the previous `sum_even`

function rewritten using `loop`

with `break `

and` continue`

instead of `while`

.

```
fun sum_even(values: &vector<u64>): u64 {
let size = vector::length(values);
let mut i = 0;
let mut even_sum = 0;
loop {
if (i >= size) break;
let number = *vector::borrow(values, i);
i = i + 1;
if (number % 2 == 1) continue;
even_sum = even_sum + number;
};
even_sum
}
```

## The Type of `while`

and `loop`

In Move, loops are typed expressions. A `while`

expression always has type `()`

.

```
let () = while (i < 10) { i = i + 1 };
```

If a `loop`

contains a `break`

, the expression has the type of the break. A break with no value has
the unit type `()`

.

```
(loop { if (i < 10) i = i + 1 else break }: ());
let () = loop { if (i < 10) i = i + 1 else break };
let x: u64 = loop { if (i < 10) i = i + 1 else break 5 };
let x: u64 = loop { if (i < 10) { i = i + 1; continue} else break 5 };
```

In addition, if a loop contains multiple breaks, they must all return the same type:

```
// invalid -- first break returns (), second returns 5
let x: u64 = loop { if (i < 10) break else break 5 };
```

If `loop`

does not have a `break`

, `loop`

can have any type much like `return`

, `abort`

, `break`

,
and `continue`

.

```
(loop (): u64);
(loop (): address);
(loop (): &vector<vector<u8>>);
```

If you need even more-precise control flow, such as breaking out of nested loops, the next chapter presents the use of labeled control flow in Move.