Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Iterable.where() should be generic and return an iterable with the given type #27827

Closed
Hixie opened this issue Nov 15, 2016 · 10 comments
Closed
Labels
area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. core-2 library-core

Comments

@Hixie
Copy link
Contributor

Hixie commented Nov 15, 2016

The following code is sound but the analyzer can't tell:

new Directory('packages')
    .listSync()
    .where((FileSystemEntity entity) => entity is Directory)
    .where((Directory dir) { // ERROR HERE
      // ...
    });

If where was defined as Iterable<T> where<T extends E>(...) then the above could work (might even work automatically given type inference?).

@pq
Copy link
Member

pq commented Nov 15, 2016

cc @bwilkerson

@alexeieleusis
Copy link
Contributor

I have had to deal with this issue too, but where is about predicates, not types, how should it behave when the predicate is not a test for a type?

@Hixie
Copy link
Contributor Author

Hixie commented Nov 15, 2016

presumably if you don't give the type explicitly, it would just return an Iterable<E>. (Maybe it would have to be annotated with @optionalTypeArgs?)

Hixie added a commit to Hixie/flutter that referenced this issue Nov 15, 2016
See flutter#6861

This silences all but two of the warnings from https://travis-ci.org/flutter/flutter/builds/176055550

One of the silenced warnings was a genuine code error.

Some of the others were correct but there was no way for the analyzer to know, and I worked around them.

The remainder are problems with the analyzer, specifically dart-lang/sdk#27827 and dart-lang/sdk#27504.
@lrhn
Copy link
Member

lrhn commented Nov 15, 2016

I'd rather add a new method to do type-filtering, like Iterable<T> Iterable.of<T>().
The where is used for many other things, and doesn't generally need the type parameter, even if it's declares as <T extends E> so we have a good default if it's omitted.

(I don't know what @optionalTypeArgs is, but I can assure you that it won't be in the platform libraries) :)

@Hixie
Copy link
Contributor Author

Hixie commented Nov 15, 2016

I'd be totally on board with .of<T> too. :-)

(@optionalTypeArgs lets you enable the require all type annotations lint but still have some type annotations be optional. The platform libraries will presumably have to add it anywhere they declare a generic type where sometimes it makes no sense to give a type. For example, the Flutter framework uses it for GlobalKey, since the type argument only makes sense if you're going to use the currentState getter, but if you're using the key with a stateless widget there's no type that could make sense.)

Hixie added a commit to flutter/flutter that referenced this issue Nov 15, 2016
See #6861

This silences all but two of the warnings from https://travis-ci.org/flutter/flutter/builds/176055550

One of the silenced warnings was a genuine code error.

Some of the others were correct but there was no way for the analyzer to know, and I worked around them.

The remainder are problems with the analyzer, specifically dart-lang/sdk#27827 and dart-lang/sdk#27504.
@sethladd sethladd added the area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. label Nov 15, 2016
@Hixie
Copy link
Contributor Author

Hixie commented Feb 6, 2017

Just ran into this again. This is definitely going to become a bigger paint point in Dart 2.0.

@srawlins
Copy link
Member

Is this now solved with Iterable.cast() and Iterable.retype()?

@eernstg
Copy link
Member

eernstg commented Apr 13, 2018

The following works with dart2js --preview-dart-2 2.0.0-dev.47.0 and it might be what you're looking for:

main() {
  Iterable<num> xs = [1, 2.2, 3, 4.2];
  xs.whereType<int>()
      .where((int i) => i > 1)
      .forEach((int i) { print(i); }); // Prints '(3)'.
}

The vm prints UnimplementedError: whereType is not yet supported, but it's coming soon.

@a14n
Copy link
Contributor

a14n commented Apr 13, 2018

Once Iterable.whereType will be supported you could add the lint prefer_iterable_whereType :)

@natebosch
Copy link
Member

Dart 2.0 contains whereType and cast and the lint prefer_iterable_wheretype. I don't think there is anything else to do here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. core-2 library-core
Projects
None yet
Development

No branches or pull requests