How do I write a for loop over a range of numbers?

← Control Flow · Ref: Q64

EK9 has a for-range loop that iterates over a numeric range using the '...' (ellipsis) operator. The range is inclusive on both ends.

BASIC INTEGER RANGE

Count from 1 to 10 (inclusive):

  for i in 1 ... 10
    stdout.println($i)

The variable i is implicitly declared as Integer. Both start and end values are included.

CUSTOM STEP WITH BY

Use 'by' to specify the step size:

  for i in 0 ... 20 by 5
    stdout.println($i)

This prints 0, 5, 10, 15, 20. The step can be any positive integer.

DESCENDING RANGE

Count downward by specifying a negative step:

  for i in 10 ... 0 by -1
    stdout.println($i)

This counts from 10 down to 0. The negative step is required for descending ranges.

EVEN NUMBERS

Combine start value and step:

  for i in 2 ... 20 by 2
    stdout.println($i)

Prints 2, 4, 6, 8, 10, 12, 14, 16, 18, 20.

VARIABLE BOUNDS

The start and end values can be variables or expressions:

  limit <- 100
  for i in 1 ... limit
    total: total + i

FLOAT RANGES

For-range works with Float values:

  for f in 0.0 ... 1.0 by 0.25
    stdout.println($f)

Prints 0.0, 0.25, 0.5, 0.75, 1.0.

DURATION AND TIME RANGES

For-range also works with Duration and Time types, making it easy to iterate over time intervals:

  thirtyMinutes <- PT30M
  start <- PT0S
  end <- PT2H
  for d in start ... end by thirtyMinutes
    stdout.println($d)

See Q31 for Date/Time types and Q32 for Duration.

NO BREAK

EK9 has no break statement. For-range loops always run from start to end. If you need to stop early, use a stream pipeline with 'head' instead (see Q125). For-range can also return values as an expression (see Q80).

See Q39 for Integer and Float types. See Q65 for iterating over collections (for-in). See Q80 for using for-range as an expression. See Q144 for why there is no break. See Q89 for stream pipelines as loop alternatives. See Q125 for head as the only early exit mechanism. See Q83 for loop expression overview. See Q283 for retry logic using for-range.

Example

defines module qa.flow.range.loop

  defines program

    ForRangeDemo()
      stdout <- Stdout()

      // === BASIC INTEGER RANGE ===

      stdout.println("Counting 1 to 5:")
      for i in 1 ... 5
        stdout.println(`  ${i}`)

      // === CUSTOM STEP ===

      stdout.println("Even numbers 2 to 10:")
      for i in 2 ... 10 by 2
        stdout.println(`  ${i}`)

      // === DESCENDING RANGE ===

      stdout.println("Countdown 5 to 1:")
      for i in 5 ... 1 by -1
        stdout.println(`  ${i}`)

      // === SUM WITH ACCUMULATION ===

      total <- 0
      for i in 1 ... 100
        total: total + i
      stdout.println(`Sum 1..100: ${total}`)

      // === VARIABLE BOUNDS ===

      start <- 3
      end <- 7
      stdout.println(`Range ${start} to ${end}:`)
      for i in start ... end
        stdout.println(`  ${i}`)

      // === FLOAT RANGE ===

      stdout.println("Float range 0.0 to 1.0:")
      for f in 0.0 ... 1.0 by 0.25
        stdout.println(`  ${f}`)

      // === NESTED RANGES ===

      stdout.println("Multiplication table (1-3):")
      for row in 1 ... 3
        for col in 1 ... 3
          stdout.println(`  ${row} x ${col} = ${row * col}`)

Common mistakes

E01070 — EK9 has no break statement. For-range loops always run from start to end. Use stream pipelines with head to limit items instead. See ek9 -h E01070 for details.

Incorrect:

for i in 1 ... 5
        stdout.println(`  ${i}`)
        if i == 3
          break

Correct:

for i in 1 ... 5
        stdout.println(`  ${i}`)

E01071 — EK9 has no continue statement. Use stream pipelines with filter to skip unwanted items instead of continue. See ek9 -h E01071 for details.

Incorrect:

for i in 2 ... 10 by 2
        if i == 6
          continue
        stdout.println(`  ${i}`)

Correct:

for i in 2 ... 10 by 2
        stdout.println(`  ${i}`)
Other ways to ask this
  • How do I loop over a range of numbers in EK9?
  • What is the for loop syntax for counting in EK9?
  • How do I iterate from 1 to 10 in EK9?
  • How do range-based for loops work in EK9?
  • What are the basic loop constructs in EK9?

Coming from another language?

Java: for (int i = 0; i < 10; i++) with C-style syntax, verbose. Python: for i in range(1, 11) with exclusive end, range() function. Rust: for i in 1..=10 with ..= for inclusive, .. for exclusive. Go: for i := 0; i < 10; i++ with C-style syntax. C++: for (int i = 0; i < 10; ++i) with C-style syntax. Kotlin: for (i in 1..10) with .. operator, downTo for descending, step for custom increment. Swift: for i in 1...10 with ... for inclusive, ..< for exclusive. C#: for (int i = 0; i < 10; i++) with C-style syntax, Enumerable.Range(). EK9: for i in 1 ... 10 with ... operator (inclusive both ends), 'by' keyword for step, works with Integer, Float, Duration, and Time types.

Keywords: float, condition, count, integer, flow, descending, iterate, ellipsis, loop, branch, by, number, step, control, ascending, range, for