Update on String Templates (JEP 459)

Clement Cherlin ccherlin at gmail.com
Fri Mar 15 18:53:00 UTC 2024


On Fri, Mar 15, 2024 at 11:39 AM Maurizio Cimadamore <
maurizio.cimadamore at oracle.com> wrote:

> Hi
>
> On 15/03/2024 16:07, Guy Steele wrote:
>
> Then again, now that I ponder the space of use cases, it may be that,
> despite my initial enthusiasm, having a separate string interpolation
> syntax may not carry its weight if its uses are relatively rare. We always
> have the option of using a string template and then applying an
> interpolation processor (which might be spelled `String.of(<template>)` or
> `(<template>).interpolate()` or some other way), and about all we lose from
> that approach is the ability to use string interpolation to specify a
> constant expression—for which we still have the old-fashioned alternative
> of using `+` concatenation. If we drop string interpolation, we can then
> drop the INTERPOLATION prefix, and we are back to a single-prefix model,
> and the remaining question is whether that prefix is optional, at least in
> some cases. Okay, I think I now have a better understanding of the
> relationships among the various proposals in the design space. Thanks for
> your patience.
>
> I think the advantage for *not* having a string interpolation prefix, is
> that then interpolation is “just another processor” e.g. a static method
> somewhere that takes a string template and returns a String. Another
> String::format, in a way. So that leads to a rather uniform design.
>
>
>
> And now that I have that better understanding, I think I lean toward (a)
> abandoning string interpolation and (b) having a single, short,
> _non-optional_ prefix for templates (“$” would be a plausible choice), on
> the grounds that I think it makes code more readable if templates are
> always distinguished up front from strings—and this is especially helpful
> when the templates are rather long and any `\{` present might be far from
> the beginning. It has a minimal number of cases to explain:
>
> “…”      string literal, must not contain \{…}, type String
> $”…”    template literal, may contain \{…}, type StringTemplate
>
> Yep, I agreee this a very principled way to look at the problem.
>
It's definitely the simplest and most consistent solution. That said,
having used the current preview, I've found STR to be both useful and
clear: It permits easy interpolation while being upfront that there is no
safety guarantee. I'd hate to give that up without a suitable replacement.
I suppose the standard library could provide "public static String
str(StringTemplate)".

Is it overly greedy to want someStringMethod(STR"interpolation \{here}")
instead of someStringMethod(str($"interpolation \{here}")) just so I can
avoid writing the extra ($ and ) ?

>
> I think we have all made an honest effort to explain string templates as a
> simple and clean superset of string literals, but now that we have
> considered the typing and overloading issues, my opinion is that it just
> isn’t possible without some amount of unwanted complication. Strings and
> string templates are just different beasts, and we would do well to
> maintain that distinction rather than trying to conflate them. Yes,
> requiring a prefix on templates would impose a small cost—perhaps we should
> regard it as a "syn-tax" rather than a “cover charge”—on every template we
> write, but I judge that cost well worth it for the readability it would buy.
>
> I agree. I don't think the ease of being able to use an un-prefixed
template *some of the time* justifies the mental, specification, and
implementation overhead of context-sensitive string-ish literal typing.

>
> (By the way, I appreciate John’s suggestion of allowing a template to
> begin with  “\{} , but this strikes me as kind of a hack rather than a
> natural use of the \{…} syntax. A distinctive single-character prefix would
> be better.)
>
> I think there’s a place for {}. E.g. where {} shines IMHO, is to allow for
> *comments* inside string templates:
>
I can't argue with that.

In the preview, an empty interpolation creates an extra fragment and a null
reference in the value array, which is weird and not particularly useful. \{
/* optional comment */ } should probably be removed as though it was never
there.

t"""
>    hello
>    this is
>    \{ /* a comment here */ }
>   a commented
>   template
> """
>
> But as a “template” prefix, it’s a bit of a lousy choice. For instance,
> one can argue that “1.0” is different from “1”. But there’s only one place
> where to look for that “.0”. Whereas, inside a text block, you can have
> many different places where the {} ends up. So, while this solves the
> problem for compiler writers, {} is not a good solution for us humans.
>
> Maurizio
>
I agree.

Cheers,
Clement Cherlin

>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-spec-observers/attachments/20240315/7db10f89/attachment-0001.htm>


More information about the amber-spec-observers mailing list