E4108

E4108#

The loop is expected to yield a value; in current syntax, add a nobreak branch.

This error occurs when the compiler infers that a for-loop is expected to yield a non-Unit value based on its context (such as the function's return type), but the loop lacks a branch to provide that value. In current MoonBit syntax, that branch is written as nobreak.

In MoonBit, when a for-loop is used in a context where a value is expected (for example, when the function returns a non-Unit type), the loop must have an nobreak branch that specifies what value to return when the loop completes normally. This is because:

  1. The loop body itself cannot yield a value (unlike loop expressions)

  2. Without a nobreak branch, there's no way to determine what value should be returned when the loop finishes without breaking

This commonly occurs in two situations:

  • When the for-loop is the last expression in a function that returns a non-Unit type

  • When the for-loop's result is assigned to a variable or used in an expression that expects a non-Unit value

Erroneous example#

///|
pub fn f(x : Int) -> Int {
  for i = 0, acc = 0; i < x; i = i + 1, acc = acc + i {
    //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Error: The for loop is
    //                                                      not expected to yield a
    //                                                      value, please add an
    //                                                      `else` branch.
  }
}

///|
pub fn g(x : Int) -> Int {
  for i in 0..<=x {

  }
}

Suggestion#

To fix this error, you can:

  • add a nobreak branch to the for-loop:

///|
pub fn f(x : Int) -> Int {
  for i = 0, acc = 0; i < x; i = i + 1, acc = acc + i {

  } nobreak {
    acc
  }
}
  • change the function's return type to Unit if you don't need to return a value from the loop:

///|
pub fn g(x : Int) -> Unit {
  for i in 0..<=x {
    ignore(i)
  }
}