<div dir="auto">Ah, I'm an idiot.<div dir="auto"><br></div><div dir="auto">There is still a proposal here somewhere...maybe. right now non jdk lists can't participate in the special casing?</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Aug 23, 2022, 9:00 PM Paul Sandoz <<a href="mailto:paul.sandoz@oracle.com">paul.sandoz@oracle.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">List.copyOf already does what you want.<br>
<br>
<a href="https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/util/List.java#L1068" rel="noreferrer noreferrer" target="_blank">https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/util/List.java#L1068</a><br>
<a href="https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/util/ImmutableCollections.java#L168" rel="noreferrer noreferrer" target="_blank">https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/util/ImmutableCollections.java#L168</a><br>
<br>
Paul.<br>
<br>
> On Aug 23, 2022, at 4:49 PM, Ethan McCue <<a href="mailto:ethan@mccue.dev" target="_blank" rel="noreferrer">ethan@mccue.dev</a>> wrote:<br>
> <br>
> Hi all,<br>
> <br>
> I am running into an issue with the collections framework where I have to choose between good semantics for users and performance.<br>
> <br>
> Specifically I am taking a java.util.List from my users and I need to choose to either<br>
> * Not defensively copy and expose a potential footgun when I pass that List to another thread<br>
> * Defensively copy and make my users pay an unnecessary runtime cost.<br>
> <br>
> What I would really want, in a nutshell, is for List.copyOf to be a no-op when used on lists made with List.of().<br>
> <br>
> Below the line is a pitch I wrote up on reddit 7 months ago for a mechanism I think could accomplish that. My goal is to share the idea a bit more widely and to this specific audience to get feedback.<br>
> <br>
> <a href="https://www.reddit.com/r/java/comments/sf8qrv/comment/hv8or92/?utm_source=share&utm_medium=web2x&context=3" rel="noreferrer noreferrer" target="_blank">https://www.reddit.com/r/java/comments/sf8qrv/comment/hv8or92/?utm_source=share&utm_medium=web2x&context=3</a> <br>
> <br>
> Important also for context is Ron Pressler's comment above.<br>
> --------------<br>
> <br>
> What if the collections api added more marker interfaces like RandomAccess?<br>
> <br>
> It's already a common thing for codebases to make explicit null checks at error boundaries because the type system can't encode null | List<String>. <br>
> <br>
> This feels like a similar problem.<br>
> If you have a List<T> in the type system then you don't know for sure you can call any methods on it until you check that its not null. In the same way, there is a set of methods that you don't know at the type/interface level if you are allowed to call.<br>
> <br>
> If the List is actually a __<br>
> Then you can definitely call<br>
> And you know other reference holders might call<br>
> And you can confirm its this case by<br>
> null<br>
> no methods<br>
> no methods<br>
> list == null<br>
> List.of(...)<br>
> get, size<br>
> get, size<br>
> ???<br>
> Collections.unmodifiableList(...)<br>
> get, size<br>
> get, size, add, set<br>
> ???<br>
> Arrays.asList(...)<br>
> get, size, set<br>
> get, size, set<br>
> ???<br>
> new ArrayList<>()<br>
> get, size, add, set<br>
> get, size, add, set<br>
> ???<br>
> While yes, there is no feasible way to encode these things in the type system. Its not impossible to encode it at runtime though.<br>
> interface FullyImmutable {<br>
> // So you know the existence of this implies the absence<br>
> // of the others<br>
> default Void cantIntersect() { return null; }<br>
> }<br>
> <br>
> interace MutationCapability {<br>
> default String cantIntersect() { return ""; }<br>
> }<br>
> <br>
> interface Addable extends MutationCapability {}<br>
> interface Settable extends MutationCapability {}<br>
> <br>
> If the List is actually a __<br>
> Then you can definitely call<br>
> And you know other reference holders might call<br>
> And you can confirm its this case by<br>
> null<br>
> no methods<br>
> no methods<br>
> list == null<br>
> List.of(...)<br>
> get, size<br>
> get, size<br>
> instanceof FullyImmutable<br>
> Collections.unmodifiableList(...)<br>
> get, size<br>
> get, size, add, set<br>
> !(instanceof Addable) && !(instanceof Settable)<br>
> Arrays.asList(...)<br>
> get, size, set<br>
> get, size, set<br>
> instanceof Settable<br>
> new ArrayList<>()<br>
> get, size, add, set<br>
> get, size, add, set<br>
> instanceof Settable && instanceof Addable<br>
> In the same way a RandomAccess check let's implementations decide whether they want to try an alternative algorithm or crash, some marker "capability" interfaces would let users of a collection decide if they want to clone what they are given before working on it.<br>
> <br>
> <br>
> --------------<br>
> <br>
> So the applicability of this would be that the list returned by List.of could implement FullyImmutable, signifying that there is no caller which might have a mutable handle on the collection. Then List.of could check for this interface and skip a copy.<br>
> <br>
> <br>
<br>
</blockquote></div>