Open andrechalella opened 5 days ago
I propose the opposite: that Iterable.generate
makes the argument required.
It's a bad design for a strongly typed language that Iterable<String>.generate(5)
is allowed (and fails to cast an int
to String
at runtime).
To create a range of integers, there should be a function, method or class somewhere specialized for that. Say
class Range extends Iterable<int> {
final int _start, _end;
const Range(int start, int end) : _start = start, _end = start <= end ? end : start;
int get length => _end - start;
bool get contains(Object? other) => other is int && _start <= other && other <= end;
Iterator<int> get iterator => _RangeIterator(_start, _end);
}
class _RangeIterator implements Iterator<int> {
int _next, _end;
int? _current;
RangeIterator(this._next, this._end);
int get current => _current ?? (throw StateError("No element"));
bool moveNext() {
if (_next < _end) {
_current = _next;
_next++;
return true;
}
_current = null;
return false;
}
}
That could be useful in many ways, and doesn't need an unsoundly typed constructor on Iterable
.
To get a sequence of integers in a List, we must do either of two suboptimal choices:
Iterable<int>.generate()
and usetoList()
:List<int>.generate()
and explicitly type the identity function:I propose
List.generate()
on integers has the identity function by default, likeIterable.generate()
.