On Oct 30, 2017, at 6:50 PM, Stuart Marks <stuart.ma...@oracle.com> wrote: > > (also includes 8184690: add Collectors for collecting into unmodifiable List, > Set, and Map)
Now I'm going to be picky about the names of the Collectors; please bear with me a moment. Consider `toUnmodifiableList` and its two cousins (`toUSet`, `toUMap`). The most natural names `toList` (etc.) are already taken. They mean "do whatever is most useful for the collector, perhaps returning unmodifiable or modifiable results". So the problem here is giving the user the option to say, "no, I really want a value-based-class-style list here; I know you can do this for me". `Collectors.toList` can't ever be upgraded in place, since the programmer is getting a Collector's Choice result, and programmers will be inadvertently relying on whatever that (undocumented) choice happens to be. I think this makes the name `toList` significantly less useful, and I for one will never want to use `toList` again, once `toUnmodifiableList` is available. Meanwhile, `toUnmodifiableList` is so ugly to the ear, eye, and fingers that it will be less used just because of its long spelling. Users should be allowed to code as if unmodifiability is a common practice, not something that must be re-announced every time I make a new temporary list. That's why `copyOf` and not `unmodifiableCopyOf` is the right move, and `toUnmodifiableList` is not. (See also Gafter's blog[1] on making NEW FEATURES look NEW. The NEW UNMODIFIABILITY will soon cease to be new but in its present form it will shout forever like an aging rocker.) To get out of this bind, I suggest picking a shorter name that emphasizes that the result is the _elements_ in the list, not the list object per se. This is a VBC[2] move, one which we need to learn to make more often, especially as value types arrive. So I suggest these names for the collectors: `elements` (for a list), `elementSet`, and `elementMap`. Same signatures, of course. Another approach to this, which recycles the old names but doesn't have the VBC vibe, is to create a second set of factories for list/set/map collectors that look just like the old ones, but behave more predictably. For example, one might try to add methods to `Collector` named `asModifiable` and `asUnmodifiable`, so people can write `toList().asModifiable()`. I don't think this works, nor is it very pretty (looks too "NEW"), although it provides a more principled fix to the Collector's Choice problem. If we go forward with the change as written, I think people will only want to remember the one `toList` and forget about his ugly brother. Only zealots like me will remember to add the extra incantation ("NEW! now Unmodifiable!"). Another, better way to recycle the name `toList` is to provide `Collectors.Modifiable` and `Collectors.Unmodifiable`, and then have users import `Collectors.Unmodifiable.toList`. This at least would move the shouting up to the static imports list and out of real code. But I think `toList` is broken and should be avoided. So I think it should be `elements`, `elementSet`, and `elementMap`. Even if you think that unmodifiability should be mentioned every time a collector collects some stuff, observe that `toUnmodifiableList` is not a strong parallel with the older API point, `Collections.unmodifiableList`. That guy creates a _view_ while `copyOf` and `elements` (my name) create non-view unmodifiable (VBC, shallowly immutable) lists. So `Collectors.toUnmodifiableList` is both ugly and ill-sorted with `copyOf`. — John [1]: http://gafter.blogspot.com/2017/06/making-new-language-features-stand-out.html [2]: https://docs.oracle.com/javase/8/docs/api/java/lang/doc-files/ValueBased.html