<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<font size="4" face="monospace">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.)</font><br>
<br>
<div class="moz-cite-prefix">On 3/19/2024 8:55 AM, Tagir Valeev
wrote:<br>
</div>
<blockquote type="cite" cite="mid:CAE+3fja8m3aVzNy047Gf==nND23idc5oBWUyrt4niPu0bB2+wA@mail.gmail.com">
<div dir="ltr">
<div dir="ltr">Hello!
<div><br>
</div>
<div>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.</div>
<div><br>
</div>
<div>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.</div>
<div>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 :-)</div>
<div><br>
</div>
<div>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.</div>
<div><br>
</div>
<div>With best regards,</div>
<div>Tagir Valeev.</div>
<div><br>
</div>
<div><br>
</div>
<div>On Tue, Mar 12, 2024 at 6:32 PM Brian Goetz <<a href="mailto:brian.goetz@oracle.com" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">brian.goetz@oracle.com</a>>
wrote:<br>
</div>
</div>
<div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div> <font size="4" face="monospace">Splitting off into a
separate thread. <br>
<br>
I would like to redirect this discussion from the
mechanical challenges and consequences to the goals and
semantics. <br>
<br>
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. <br>
<br>
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.))<br>
<br>
<br>
<br>
</font><br>
<div>On 3/12/2024 1:24 PM, Tagir Valeev wrote:<br>
</div>
<blockquote type="cite">
<div dir="ltr">
<div>Hello, Maurizio!</div>
<div><br>
</div>
<div>Thank you for the detailed explanation!</div>
<br>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">On Mon, Mar 11,
2024 at 1:16 PM Maurizio Cimadamore <<a href="mailto:maurizio.cimadamore@oracle.com" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">maurizio.cimadamore@oracle.com</a>>
wrote:<br>
</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div>
<div>
<p style="margin:0px 0px 1.2em">Hi all,<br>
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 <em>convertible</em> to string
templates. Or, (c) use target-typing. All
these approaches have some issues, discussed
below.<br>
</p>
<p style="margin:0px 0px 1.2em">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:</p>
<pre style="font-family:Consolas,Inconsolata,Courier,monospace;font-size:1em;line-height:1.2em;margin:1.2em 0px"><code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;background-color:rgb(248,248,248);white-space:pre-wrap;overflow:auto;border-radius:3px;border:1px solid rgb(204,204,204);padding:0.5em 0.7em;display:block">format(StringTemplate) // 1
format(String, Object...) // 2
</code></pre>
<p style="margin:0px 0px 1.2em">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.</p>
<p style="margin:0px 0px 1.2em">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.</p>
</div>
</div>
</blockquote>
<div>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.</div>
<div><br>
</div>
<div>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.</div>
<div><br>
</div>
<div> </div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div>
<div>
<p style="margin:0px 0px 1.2em">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.</p>
</div>
</div>
</blockquote>
<div>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.</div>
<div><br>
</div>
<div>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.<br>
</div>
<div><br>
</div>
<div>With best regards,</div>
<div>Tagir Valeev.</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div>
<div> </div>
</div>
</blockquote>
</div>
</div>
</blockquote>
<br>
</div>
</blockquote>
</div>
</div>
</blockquote>
<br>
</body>
</html>