Open nex3 opened 11 years ago
Added Library-Collection label.
Natalie: does UnmodifiableListView do the trick?
http://api.dartlang.org/docs/releases/latest/dart_collection/UnmodifiableListView.html
That's definitely the sort of thing I'm looking for, yes. Read-only views for Maps and Sets are still missing, though.
Upon further inspection, UnmodifiableListView isn't really enough... it only implements Iterable, not Collection (let alone List).
UnmodifiableListView extends UnmodifiableListBase which is a typedef for mixing in ListBase with UnmodifiableListMixin. ListBase is a typedef for mixing in Object with ListMixin. and ListMixin implements List. -> UnmodifiableListView should implement List.
The editor and dart_analyzer report this as not being the case at
0.4.7.5 r21658
Is this an analyzer bug?
Yes, it is an analyzer bug. I made a smoke test that ran through the vm,dart2js,dart2dart with testCases exposed as UnmodifiableListView.
expect(testCases is Object, isTrue); expect(testCases is List, isTrue); expect(testCases is Map, isFalse); expect(testCases is UnmodifiableListView, isTrue);
I'm marking this as high priority, since if unittest is going to use UnmodifiableListView then it's going to cause analyzer warnings for practically every project.
Removed Priority-Medium, Area-Library, Library-Collection labels. Added Priority-High, Area-Analyzer labels.
See issue #10055
I'm reassigning this to dart:collections, since issue #10055 is now tracking the analyzer bug. View classes are still needed for Map, Queue, and Set.
Removed Priority-High, Area-Analyzer labels. Added Priority-Medium, Area-Library, Library-Collection labels.
Removed Type-Defect label. Added Type-Enhancement label. Marked this as being blocked by #10128.
UnmodifiableMapView has shipped. Just need a view for Set now
Changed the title to: "Request: dart:collection UnmodifiableSetView".
UnmodifiablSetView is now provided by the collection package: https://pub.dartlang.org/documentation/collection/latest/collection/UnmodifiableSetView-class.html
I'd like to keep this open. It's really confusing that all but one of the core collection types has an unmodifiable view in dart:collection
.
@kevmoo @nex3 Hey! Is there possible to add read only types to dart:collection? Right now you know about modifications at runtime phase, because they throw exceptions. That's not ergonomic.
I think there's 2 options:
CC @lrhn
@aetet
Dart has considered read-only superinterfaces like ReadOnlySet
before, and decided against it.
The primary concern has always been that it's one extra user concern. Whenever you make a function which takes a List
as argument, you'd have to consider whether it should be a ReadOnlyList
. Whenever you return a list, you have to decide as well. And that's not the only variant of lists, we also have fixed-lengh lists, which are not completely unmodifiable.
In Dart 1, the current approach of having one List
type (and Set
and Map
) and some implementations which implemented less than the entire interface, was a good fit for the language.
It can be argued that in Dart 2, with stronger type checking, a more type-heavy approach would fit better, but we have decided not to go that way. The user-complexity concern still applies, and it would be a large breaking change to modify the existing APIs to accept or return ReadOnlyList
in some places, because subclasses and use-places need to adapt too. (For example, if we introduce ReadOnlyList
as a super-interface of List
, and we change a function foo
to return ReadOnlyList
instead of List
, then var x = foo(); if (something) x = [];
would break.)
As for helping the analyzer recognize unmodifiable lists, that still requires a marker type of some sort.
It's not enough to add an empty marker interface (often considered an antipattern) for being unmodifiable and implement it on the unmodifiable collection implementation classes. That information is lost the moment you do List<int> myList = List.unmodifiable(...);
. So, to make something visible to the analyzer, we need UnmodifiableList<int> myList = List.unmodifiable(...);
, where UnmodifiableList
is a subtype of List
, one which is recognized specially by the analyzer, so that it can warn if you call modifying methods on it. That's still too intrusive, it introduces a new type with no semantic meaning, only to allow the analyzer to detect it. I guess the best, and least intrusive approach would be:
@unmodifiable
List<int> myList = ...;
which tells the analyzer that the variable contains an unmodifiable collection, and if the analyzer recognizes the collection, then it can warn about calls to modifying members. (If it doesn't know the interface, maybe it can warn about calls to members where the type variable occurs contravariantly).
In short: We have no plan to change the language or the libraries in this direction, but it might be possible for the analyzer to do something using metadata annotations (almost anything can be done that way).
Thanks for explanation @lrhn
I'd like to come back to the initial problem.
Here's my case for having UnmodifiableSetView
in dart:collection
instead of a separate pub package:
dart:collection
has UnmodifiableListView
, UnmodifiableMapView
, but no UnmodifiableSetView
. This seems like an inconsistency, and it suggests that there is no official UnmodifiableSetView
at all. Because otherwise, why would it not be with the other basic unmodifiable collections? Set
got a literal ({ o1, o2 }
) in Dart, which suggests it's at the general level of popularity and "basic-ness" of List
and Map
.package:collection
and its implementation of UnmodifiableSetView. And I knew (roughly) what I was looking for. I think we can assume that most developers will not go searching like that.I am all for keeping the core libraries clean. But I think the problems mentioned above outweigh the downsides of adding one additional class, especially since dart:collection
already has 26 classes. (I would be way more wary about adding a class to an import that carries 5 or 10 classes.)
I see no practical reason to punt on this given the other classes we've shipped in this package!
+1 to nex3's comment:
can we move UnmodifiableSetView
from the collection package to dart:collection already?
i just wasted a bunch of time trying to figure out where this basic data structure is.
searching the api docs doesn't help and google search doesn't reveal the answer very quickly either.
by far the most expected place for this would be dart:collection.
The dart:async library contains nice StreamView and StreamSinkView classes for providing extendable views over existing objects. It would be nice if the same sorts of classes were provided for various collection types -- especially if there were variants that were read-only.