-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
List.map should specialise the return type of Collection.map #4054
Comments
I agree that if we have a map function on List, it should be declared to return a List too. That's possible, but it's not optimal. Perhaps we should also have the utility 'map' instance method that works on the current collection and creates another of the same kind, but it's not obvious how to get a proper generic type for the result collection. That really requires generic methods (or reflection, but I'd prefer to not depend on that in what should be simple collection operations). Removed Type-Defect label. |
This comment was originally written by @seaneagan This exact same issue exists for Collection#filter(issue #1062), so both should be solved consistently. I think using constructors instead of instance methods for Collection transformations breaks down when considering chaining. Instance methods are more fluent and readable. More importantly though, if using constructors, I assume they will eagerly copy each element of the input. When chaining this causes intermediate Collections which copy each element to be created, which will not even be used, and the result cannot act as a "view" which updates when the original Collection changes. This is discussed in more detail in issue #1305. I'm not sure why generic methods are seen as more complicated than generic constructors, they seem like the obvious solution to Collection#map and Collection#reduce (issue #1649). The "as" cast operator might also help. |
Using constructors isn't as fluent as methods. If we have both, then we have more choices wrt. making the generated values lazy. E.g., we could have an Iterator<T>.map(Iterable source, T mapping(var value)) constructor that creates a lazy iterator, while Set<T>.map(Iterable source, T mapping(var value)) eagerly creates a populated set object. The instance method can then be eager (which is what I would expect for an "operator-like" method), since you have a lazy alternative anyway. You should also be able to get special views of existing collections, e.g., a Set view of the keys of a Map, or a Collection view of its values. These would be actively backed by the original collection and reflect changes.
|
This comment was originally written by @seaneagan I would expect the fluent methods (including "map" and "filter"/"findAll") to also return "views", so that you can build up composite transformations without ever having to do any copying or unnecessary iteration. You can then compose these with the existing copy constructors in the less common case of needing a "snapshot". Also, if generic methods might ever make it into Dart, why not just rely on the "as" cast operator as a temporary work around, instead of adding duplicative constructors? Example: var strings = <String>['bar', '5', 'bAz', 'BaZ']; // usually just need a view // can later add an item to "strings" and have it reflected in "view" // strings never needs to be fully iterated or copied to do the following // can snapshot a view using a copy constructor // can even use a copy constructor from a different type |
Added NotPlanned label. |
This issue was originally filed by sammcca...@google.com
Collection.map() returns a Collection.
In practice I think List.map() always returns a List, but it would be nice if we could rely on this!
The text was updated successfully, but these errors were encountered: