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:
Trait system at this point is already a simplified version of Rust's trait system, and copying more of Rust's trait makes sense as we know overall system is still coherent and works well, and it's familiar.
Associated types should be simpler to implement as they don't make trait resolving process any more complicated.
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 wanta
to be some kind of iterator that yields elements of some type, which will be the type ofx
.For example, for the vector type:
There are two ways of implementing an iterator type:
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:
Trait system at this point is already a simplified version of Rust's trait system, and copying more of Rust's trait makes sense as we know overall system is still coherent and works well, and it's familiar.
Associated types should be simpler to implement as they don't make trait resolving process any more complicated.