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