Skip to content

Latest commit

 

History

History
49 lines (36 loc) · 1.42 KB

iterators.md

File metadata and controls

49 lines (36 loc) · 1.42 KB

Iterators

Iterators don't exist in this language because you can just write a function in the 'internal iterator' style and it compiles to efficient code with no extra work.

Importantly break, continue and return are lexically bound so they work exactly how you'd expect. This makes it nice to make infinite iterators that you can pause later. See the transducers section for high level operators.


Here is an example of a custom iterator over a 2d grid. The break and continue target is lexically scoped so it knows to break out of both while loops, so it just works how you would expect.

The __iterate is a special constant that the default metaclass looks for.

type Range2d:
  w: int
  h: int

  # This tells the compiler what function to use for iteration
  __iterate :: range2d_iterate

# the loop body is passed as a template parameter 'f'. and the function must be marked @inline
fn range2d_iterate!(f)(range: Range2d) void @inline:
  for j in Range(0, range.h):
    for i in Range(0, range.w):
      f(vec2i(i, j))

type Range:
  start: int
  end: int
  __iterate :: range_iterate

fn range_iterate!(f)(range: Range) void @inline:
  i := range.start
  while i < range.end:
    f(i)
    i += 1

type vec2i:
  x: int
  y: int

fn main():
  range := Range2d(32, 64)
  for vec in range:
    if vec.x * vec.y > 256:
      continue # continue does the right thing
    print(vec.x, vec.y)