Update on String Templates (JEP 459)

Tagir Valeev amaembo at gmail.com
Tue Mar 12 17:24:10 UTC 2024


Hello, Maurizio!

Thank you for the detailed explanation!

On Mon, Mar 11, 2024 at 1:16 PM Maurizio Cimadamore <
maurizio.cimadamore at oracle.com> wrote:

> Hi all,
> we tried mainly three approaches to allow smoother interop between strings
> and string templates: (a) make String a subclass of StringTemplate. Or (b)
> make constant strings bs *convertible* to string templates. Or, (c) use
> target-typing. All these approaches have some issues, discussed below.
>
> The first approach is slightly simpler, because it can be achieved
> entirely outside of the Java language. Unfortunately, adding “String
> implements StringTemplate” adds overload ambiguities in cases such as this:
>
> format(StringTemplate) // 1
> format(String, Object...) // 2
>
> This is actually a very important case, as we predice that StringTemplate
> will serve as a great replacement for methods out there accepting a
> string/Object… pack.
>
> Unfortunatly, if String <: StringTemplate, this means that calling format
> with a string literal will resolve to (1), not (2) as before. The problem
> here is that (2) is not even applicable during the two overload resolution
> phases (which is only allowed to use subtyping and conversions,
> respectively), as it is a varargs method. Because of this, (1) will now
> take the precedence, as that’s not varargs. While for String::format this
> is probably harmless, changing results of overload selection is something
> that should be done with care (esp. if different overloads have different
> return types), as it could lead to source compatibility issues.
>
I would still like to advocate for String <: StringTemplate solution. I
think that the overloading is not a big problem. Simply making String
implements StringTemplate will not break any of existing code because there
are no APIs yet that accept the StringTemplate instance. The problem may
appear only when an API author actually adds such an overload and does this
in an incompatible way with an existing String overload. This would be an
extremely bad design choice, and the blame goes to the API author. You've
correctly mentioned that for String::format this is harmless because the
API is well-designed. We may suggest in StringTemplate documentation that
the API designers should provide the same behavior for foo(String) and
foo(StringTemplate) when they add an overload.

I must say that we already had an experience of introducing new interfaces
in the hierarchy of widely-used library classes. Closable got AutoClosable
parent, StringBuilder became comparable, and so on. So far, the
compatibility issues introduced were tolerable. Well, probably I'm missing
something but we have preview rounds just for this purpose: to find out the
disadvantages of the approach.



> On top of these issues, making all strings be string templates has the
> disadvantage of also considering “messy” strings obtained via concatenation
> of non-constant values string templates too, which seems bad.
>
I think that most of the APIs will still provide String overload. E.g., for
preparing an SQL statement, it's a perfectly reasonable scenario to have a
constant string as the input. So prepareStatement(String) will stay along
with prepareStatement(StringTemplate). And people will still be able to use
concatenation. I don't think that the absence of String <: StringTemplate
relation will protect anybody from using the concatenation. On the other
hand, if String actually implements StringTemplate, it will be a very
simple static analysis rule to warn if the concatenation occurs in this
context. If the expected type for concatenation is StringTemplate, then
something is definitely wrong. Without 'String implements StringTemplate',
one will not be able to write a concatenation directly in StringTemplate
context. Instead, String-accepting overload will be used, and the expected
type will be String, so static analyzer will have to guess whether it's
dangerous to use the concatenation here. In short, I think that it's
actually an advantage: we have an additional hint here that concatenation
is undesired. Even compilation warning could be possible to implement.

So, I don't see these points as real disadvantages. I definitely like this
approach much more than adding any kind of implicit conversion or another
literal syntax, which would complicate the specification much more.

With best regards,
Tagir Valeev.

>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-spec-experts/attachments/20240312/74123307/attachment.htm>


More information about the amber-spec-experts mailing list