dart-lang / language

Design of the Dart language
Other
2.66k stars 205 forks source link

map a List of Streams of different types to Array of Arrays of corresponding types #800

Open raveesh-me opened 4 years ago

raveesh-me commented 4 years ago

In flutter, I am trying to take in an Array of streams of different types, handle the listening and dispose myself and turn them into nested providers.

A simpler description of this problem would be:

  1. Start with n Lists of different types
  2. Convert them into a List of Streams of different types
  3. Map the List of streams of different types back into a List of Lists of corresponding types.
lrhn commented 4 years ago

Is the issue here that you want to preserve the type of the lists, because just retaining the data is simple.

Future<List<List>> roundtrip(List<List> lists) async {
  var streams = [for (var list in lists) Stream.fromIterable(list)];  // We lose the type here.
  var futureLists = [for (var stream in streams) stream.toList()];
  var listsAgain = await Future.wait(futureLists);
  return listsAgain;
}

Losing the type is probably inevitable.

If the code must work with lists of different types, then it cannot know the type of the individual lists. There is no way to extract the run-time type of the list and use it to create a stream of the same type. The List.toList and List.toSet can do that because it is internal to the list itself and has access to its type parameter, but there is no List.toStream. So, the stream has to be created without knowing the actual type of the list, and therefore the stream will not have that type.

The only thing that could help here was a way to extract the type parameters from the run-time type of an object, like the int from a List<int>. There is currently no way to do that in Dart.

The same thing happens if you get streams of unknown run-time types as input and have to handle the elements. You can listen for the events, but all you know is that they are objects, you can't access the element type itself.

raveesh-me commented 4 years ago

Yes, this clearly spells what is missing

Now how do we solve this?

lrhn commented 4 years ago

That would require an "open type"-like functionality, or a pattern matching/destructuring functionality, which allows you to extract the type parameter of, say, a List implementation as a new type parameter.

Dart does not currently have that.

It's something we do want to add at some point (because it's useful, and Dart is uniquely positioned to have this feature because it actually retains type arguments at run-time). It's not a common feature in programming languages, so we have to be extra careful in the design - there is not a lot of existing knowledge to build on in comparable languages.