sdk icon indicating copy to clipboard operation
sdk copied to clipboard

Dart 3 core library changes

Open mit-mit opened this issue 2 years ago • 1 comments

Generally it's hard to evolve the Dart core libraries, as most changes tend to be potentially widely breaking. For example, adding a new member to a class in the core libraries can be breaking to any code that that implements that class, given all Dart classes are implicit interfaces.

While we still don't want major breaking changes in Dart 3 outside of the non-null discontinuation, we have an opportunity to be mildly breaking.

The concrete list of discussions is still under discussion.

dart:core

  • Add Iterable.whereNotNull() as an extension to Iterable in dart:core (currently in package:collection as an extension)

  • Add Iterable.firstOrNull() / Iterable.lastOrNull() / Iterable.elementAtOrNull()as extension methods to Iterable in dart:core (some currently in package:collection as an extension)

  • Add DateTime.copyWith(). Long standing request. As an extension method, to avoid breakage.

mit-mit avatar Sep 08 '22 13:09 mit-mit

Maybe add a name property to FileSystemEntity and change the firstWhere() method from Iterable to return a nullable value...

Wdestroier avatar Sep 09 '22 13:09 Wdestroier

With records being a thing, we may want to embrace them.

We have a number of "indexed" iterable extensions in package:collection that would otherwise be worthy candidates for inclusion in dart:core, but with records, we can instead introduce a single "add index to iterable" operation:

extension IterableExtension<T> on Iterable<T> {
  Iterable<(int, T)> get indexed sync* {
    var index = 0;
    for (var element in this) yield (index++, element);
  }
}

Then you would be able to do:

for (var (i, e) in something.indexed) {
  print("#$i: $e");
}

(We'll be missing some affordances in the first release, for example we probably won't have patterns in parameters, so not everything will be as smooth as the for-in.)

We should consider whether there are other uses of records that afford a similar big result for a small effort.

lrhn avatar Sep 27 '22 11:09 lrhn

Usually this one is mentioned as well:

extension MapExtension<K, V> on Map<K, V> {
  Iterable<(K, V)> get keyed sync* {    
    for (var element in this.entries) yield (element.key, element.value);
  }
}

// Example usage.

void main() {
  var map = {1: "one", 2: "two"};
  for (var (key, value) in map.keyed) {
    print('$key: $value');
  }
}

eernstg avatar Sep 27 '22 13:09 eernstg

The Map.keyed here is mostly redundant with the existing Iterable<MapEntry<K,V>> get entries.

You can do for (var MapEntry(:key, :value) in map.entries) ... with pattern matching. If we can get rid of the redundant MapEntry too, it would be even better.

(It would be nice to make MapEntry an alias for ({K key, V value}), but that would break code currently using the constructor. I'm more inclined to make it either a struct, or make it a view on ({K key, V value}), preferently a transparent view which can be cast in either direction, if such a thing exists. Really, I just want a place to hang the constructor.)

lrhn avatar Sep 27 '22 14:09 lrhn

The DateTime.copyWith extension is now merged: https://dart-review.googlesource.com/c/sdk/+/258541

spydon avatar Oct 20 '22 11:10 spydon

If I could ask for anything crazy in Dart 3, I would go with print("value is", a). I alwaaays struggle with Dart syntax, and it is possible to implement that without varargs. Since print is not supposed to run in release mode, the minimal performance impact is negligible.

https://github.com/dart-lang/sdk/issues/49084

bernaferrari avatar Dec 22 '22 16:12 bernaferrari

Hey @lrhn can you please check the list at the top (which I updated) to see if it's complete for 3?

mit-mit avatar Apr 10 '23 12:04 mit-mit

LGTM.

lrhn avatar Apr 12 '23 12:04 lrhn