Does String extend StringTemplate? (Was: Update on String Templates (JEP 459))
Brian Goetz
brian.goetz at oracle.com
Tue Mar 19 13:35:47 UTC 2024
I feel your pain! We walked many of these steps, for many of the same
reasons. Each initially-promising approach (subtyping, poly
expressions, target typing) turned out to have more drawbacks than
benefits. But I agree it would be nice if one could just use a string
literal where a string template is needed -- no one would be confused
(when it works right.)
On 3/19/2024 8:55 AM, Tagir Valeev wrote:
> Hello!
>
> Thank you for splitting the thread. I think that String is a
> StringTemplate in the same sense as zero is also a number, identity is
> also a function, and empty set is also a set. A degenerate case is
> important for generalization, as you don't have to think about it when
> it actually appears.
>
> That said, now I have started to doubt this idea. So far I advocated
> for 'string should be string template', but what I really want is that
> 'string literal should be string template', which, while similar, is
> not the same. Indeed, for unification we don't actually need to
> support non-literal strings.
> It would be interesting to create a subclass of String like
> StringLiteral, which is constructed only from literals and implements
> StringTemplate. However, it will be a huge compatibility disaster.
> Now, my thought goes into some kind of implicit conversion from String
> literal (and only from literal) to StringTemplate, which was already
> discussed elsewhere, so the discussion is already far ahead of my
> thoughts :-)
>
> To conclude, what I really wanted is a uniform way to specify
> StringTemplate with 0 embedded expressions and StringTemplate with 1+
> embedded expressions. E.g., if we require a prefix for all string
> templates like ST"...", then this desire will be satisfied. If we
> don't introduce the prefix but can use String literal in every context
> where StringTemplate literal is possible (like it's in the current
> preview), then my desire is also satisfied. I see the drawbacks in
> every solution, so for now I don't have a strong preference.
>
> With best regards,
> Tagir Valeev.
>
>
> On Tue, Mar 12, 2024 at 6:32 PM Brian Goetz <brian.goetz at oracle.com>
> wrote:
>
> Splitting off into a separate thread.
>
> I would like to redirect this discussion from the mechanical
> challenges and consequences to the goals and semantics.
>
> If we are considering "String extends StringTemplate", we are
> making a semantic statement that a String *is-a* StringTemplate.
> While I can imagine convincing oneself that this is true "if you
> look at it right", this sets off all my "self-justification"
> detectors.
>
> So, I recommend we step back and examine why we think this is a
> good idea before we descend into the mechanics. My suspicion is
> that this is motivated by "I want to be able to automatically use
> String where a StringTemplate is desired", and that this seems a
> clever-enough hack to get there. (I think we probably also need
> to drill further, into "why do we think it is important to be able
> to use String where StringTemplate is desired", and I suspect
> further that part of it will be "but the APIs are not yet fully
> equilibrated" (which would be a truly bad reason to give String a
> new supertype.))
>
>
>
>
> On 3/12/2024 1:24 PM, Tagir Valeev wrote:
>> 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-observers/attachments/20240319/296767f6/attachment-0001.htm>
More information about the amber-spec-observers
mailing list