fir-lang / fir

MIT License
26 stars 3 forks source link

Type system support for iterators #21

Closed osa1 closed 2 months ago

osa1 commented 3 months ago

For for-in loops we need some kind of iterator type, but the type system is not expressive enough yet to support it.

In a loop like for x in a: ... we want a to be some kind of iterator that yields elements of some type, which will be the type of x.

For example, for the vector type:

type Vec[T]:
    data: Array[T]
    len: U32

type VecIter[T]:
    vec: Vec[T]
    idx: U32

There are two ways of implementing an iterator type:

# (1) Using multiple parameters.
trait Iterator[C, A]:
    fn next(self: C): Option[A]

impl[T] Iterator[VecIter[T], T]:
    # Here we could make type of `self` implicit and use the first type
    # parameter of the trait as the self type.
    fn next(self: VecIter[T]): Option[T] = ...

# (2) Using associated types.
trait Iterator[C]:
    type Item

    fn next(self): Option[Item]

impl[T] Iterator[VecIter[T]]:
    type Item = T

    fn next(self): Option[T] = ...

Because in (1) the method refers to all of the type parameters of the trait, there is no ambiguity, and the difference between these two is only syntactic.

I don't know any other way to make for-in loops work, so we should implement one of these.

I'm inclined towards (2) for the following reasons:

osa1 commented 2 months ago

I've implemented associated types. Here's a test that defines an iterator trait and an instance: https://github.com/fir-lang/fir/blob/fefa9c2c25dd81508938f7755a23311254722de6/tests/Iterator.fir.