Some observations on JEP draft of Templated Strings and Policies

Stuart Marks stuart.marks at oracle.com
Wed Oct 20 23:06:48 UTC 2021


> I don't like the idea of TemplatedString having a dependency on java.util.List, as it means that the latter would now be hard-coded into the language.
> A more sensible solution would be any java.lang.Iterable, which is already hard-coded into the language due to it's usage in for-each loops.
> This one, as oposed to java.util.List is a very simple and concise interface.

> Yes, it will be new for a class of java.lang to have an API dependency on java.util.List.
> 
> java.lang.String or java.lang.Throwable already have an implementation dependency (not an API dependency) on java.util.List and java.lang.invoke.MethodType has an API dependency on java.util.List. So i'm not sure there is a sacred line drawn in the sand since we have modules and java.lang and java.util are both inside the module java.base

There are several things in java.lang that already use java.util.List, and many more 
in "sub-packages" java.lang.constant, java.lang.invoke, java.lang.management, and 
java.lang.module. See

 
https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/class-use/List.html#java.lang

A few uses of Collection, Set, and Map have also crept in. But it turns out that we 
crossed this bridge a long time ago; System::getenv has returned a Map since JDK 1.5:

 
https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/System.html#getenv()

That said, we do want to keep the language at "arm's length" from the collection 
libraries. We don't want to have a system where everything can depend on everything 
else. (That was sort-of the case prior to Java 9. Much of the groundwork for 
modularizing the JDK was breaking these dependencies.)

Unfortunately the Java language (separate from the library) has only two means of 
expressing aggregations: arrays and classes. Arrays have the unfortunate property of 
being mutable. If you look at the values() method of any enum, for example, they all 
return arrays. This is sort-of ok from an API standpoint, but since arrays are 
mutable, it requires every call to the values() method to make a defensive copy. As 
a result, every library that wants to iterate an enum gets the values() array once 
and caches it.

To avoid issues like this, TemplatedString might create a bespoke class within 
java.lang (possibly a nested class) to represent its values and segments. But to be 
usable, this class would need to have convertors to and from collections, and it 
would have to have methods to access elements, etc. At a certain point, one would 
ask, "Why isn't this just a List?"

It's true that Iterable is a simple and concise interface, and it's already a 
dependency of the language on the library. But it's underpowered: the only thing you 
can do is iterate it. For this reason, from time to time there are proposals to add 
various operations to Iterable. But these end up with a half-complete version of 
Collection, when what you really want is Collection. (Or possibly List.)

Finally, if we admit to ourselves that LinkedList is an outlier, the main useful 
implementations of List are actually wrappers around arrays. And it turns out that a 
List is a pretty decent way to represent a read-only array.

s'marks


More information about the jdk-dev mailing list