Iterable
This proposal has been accepted in principle.
It is currently under active development.
Parts might be incomplete or missing in Zirric.
Introduction
This proposal introduces standard @Countable and @Iterable annotations for
collection-like types, which is used by for ... <- ... loops.
Also introduces Range and ClosedRange data types as examples of countable and iterable.
Motivation
Zirric needs a consistent way to describe collection behavior. Without a shared
protocol, each type defines bespoke iteration helpers, and tooling cannot
recognize which values support iteration or have lengths.
Currently only arrays can be used to iterate over.
Proposed Solution
Define two annotations in the prelude future module:
@Countablefor types with a length.@Iterablefor types that can yield values in aforloop.
@Proposal(ZE_010)
attr Countable {
@Returns(Int)
length(@Has(Countable) value)
}
@Proposal(ZE_010)
attr Iterable {
iterate(@Has(Iterable) value, @Func yield)
}
Range Types
Add Range and ClosedRange as iterable, countable data types.
@Countable(_rangeCount)
@Iterable(_rangeIterate)
data Range { @Int start, @Int end }
@Countable(_rangeCount)
@Iterable(_rangeIterate)
data ClosedRange { @Int start, @Int end }
Detailed Design
@Countable.lengthreturns the length of a value.@Iterable.iteratereceives the value and ayieldfunction, returning when
iteration completes oryieldreturns false.- The
for element <- valuesyntax invokesiterateunder the hood.
The internally used yield function has the signature:
@Func
@Returns(Bool)
yield(element)
When starting the loop, the iterate function of the @Iterable annotation is extracted.
Then iterate is called. The yield function passed to iterate will execute the body of the loop.
When leaving the loop early via break or return, yield will return false, causing iterate to stop iteration early.
For arrays a more efficient implementation may be used that does not require function calls per element.
Changes to the Standard Library
- Add
@Countable,@Iterable,Range, andClosedRangein
prelude. prelude.Dict,prelude.Stringandprelude.Arrayshould all be annotated with@Countableand@Iterable.
Alternatives Considered
- A single
Iterableannotation with optionallength, which makes
length-dependent APIs harder to check. - Hardcoding iteration support per type, which limits extensibility.
Acknowledgements
- Inspired by iterator protocols in Swift and Python.