Fwd: Syntax question for JEP 430: String Templates

Jim Laskey james.laskey at oracle.com
Tue Apr 11 18:35:43 UTC 2023



Begin forwarded message:

From: Jim Laskey <james.laskey at oracle.com>
Subject: Re: Syntax question for JEP 430: String Templates
Date: April 11, 2023 at 1:11:58 PM ADT
To: Octavia Togami <octavia.togami at gmail.com>
Cc: amber-spec-comments at openjdk.org


Octavia,


I’m assuming you want ${…} used because that’s what many other languages use (if that is not the reason, apologies). I would argue that it is an advantage for Java not to use what other languages use. More on that toward the end of this reply.

JEP 430 indicates why \{…} was chosen and I don’t think the reasoning is weakened by the processor expression prefix requirement.

- Backslash was chosen because the combination of \{ would not create compatibility issues with older Java source.

- Braces were chosen because it is less likely that braces would be used in an embedded expression (versus parentheses and brackets). Note that Swift uses \(…).

Using ${…} to indicate embedded expressions would create two distinct categories of quoted elements, that is, ${…} would be lexically different for strings versus templates. Sounds simple, but tools wouldn't know which way to tokenize the quoted element until the tool’s grammar detected the "processor dot template" context (and note that processor can be a complex expression). Since most tools separate scanning (lexicon, tokens) from parsing (grammar) this forces the tooling to provide some sort of feedback between the lexicon and grammar — gets messy.

Using \(…) makes it easy for javac to tokenize both strings and templates without feedback from the parser. Note that you would have to add a new escape sequence for $ if you want to use $ in the template.)

Other languages can support ${…} at the lexicon level because their strings were designed to support ${…} from the beginning or have simple ways to indicate that the quoted element needs to be treated differently — different quotes, tag prefix, … .

Back to what I stated at the beginning, I think that \{…} is an advantage for string templates in much the same way that triple quotes works for text blocks, \{…} doesn’t conflict with other languages. Java serves a polyglot universe, where it is not uncommon to embed other language source in a Java app. For example;

Object result = JAVASCRIPT."""
    let header = "Templates Literals";
    let tags = ["template literals", "javascript", "es6"];

    let html = `<h2>${header}</h2><ul>`;
    for (const x of tags) {
      html += `<li>${x}</li>`;
    }

    html += `</ul>`;
    """;

or

Object result = BASH."""
    Recipient=”admin at example.com<mailto:admin at example.com>”
    Subject=”Greeting”
    Message=”Welcome to our site”
    `mail -s ${Subject} ${Recipient} <<< ${Message}`
    """;


Though you would not have the advantage of embedded expressions, it is also possible to use ${…} for your own style of template. We assume existing template libraries will provide similar StringTemplate “bridging".

static final StringTemplate.Processor<StringTemplate, RuntimeException> MY_STYLE = st -> {
    String text = st.interpolate();
    Pattern p = Pattern.compile("\\$\\{(.*?)\\}");
    Matcher m = p.matcher(text);
    List<String> fragments = new ArrayList<>();
    List<String> values = new ArrayList<>();
    int last = 0;

    while (m.find()) {
        fragments.add(text.substring(last, m.start()));
        values.add(m.group(1));
        last = m.end();
    }
    fragments.add(text.substring(last));

    return StringTemplate.of(fragments, values);
};


public static void main(String[] args) {
    StringTemplate mailer = MY_STYLE."""
            Dear ${name},

            This is to inform you that your ${package} will be
            delivered on ${date}.

            Respectfully,

            Big Shop
            """;
    Map<Object, Object> data = Map.of(
            "name", "Joan",
            "package", "bicycle",
            "date", "May 31"
    );
    System.out.println(StringTemplate.interpolate(
            mailer.fragments(),
            mailer.values().stream().map(data::get).toList()
        ));
}

-----------------------------------------------------


Dear Joan,

This is to inform you that your bicycle will be
delivered on May 31.

Respectfully,

Big Shop


-----------------------------------------------------

Hope this frames a better understanding.

Cheers,

— Jim

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


More information about the amber-spec-experts mailing list