dart-lang / core

This repository is home to core Dart packages.
https://pub.dev/publishers/dart.dev
BSD 3-Clause "New" or "Revised" License
18 stars 7 forks source link

Make List.generate() generator function optional, like Iterable.generate() #721

Open andrechalella opened 5 days ago

andrechalella commented 5 days ago

To get a sequence of integers in a List, we must do either of two suboptimal choices:

  1. Start from Iterable<int>.generate() and use toList():
List<int> list = Iterable<int>.generate(n).toList();
  1. Start from List<int>.generate() and explicitly type the identity function:
List<int> list = List<int>.generate(n, (x) => x);

I propose List.generate() on integers has the identity function by default, like Iterable.generate().

lrhn commented 1 day 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.