Update on String Templates (JEP 459)
Guy Steele
guy.steele at oracle.com
Wed Mar 13 18:03:02 UTC 2024
Now that Maurizio has made quite clear the need for string templates to be understood as something distinct from strings, when used for security-related purposes (the need to ensure that material from interpolated expressions is vetted by the template processor), I agree that 2b is undesirable. We do not want to tempt users to think that
“Hello, \{x}”
and
“Hello “ + x
are completely interchangeable.
On the other hand, there are applications where vetting is not important, and while the rest of this sentence is explicitly stated as a non-goal of JEP 459, I suspect we do, secretly, actually want users to feel free to use templates rather than “+” concatenation to construct "plain old unvetted strings”. In the current state of JEP 459, this can be indicated in a clear way:
STR.”Hello, \{x}”
And of course STR can be replaced by the name of some other template processor.
Brian has now proposed that the template processor mechanism is clunky and redundant, and would be better handled by just providing methods that take arguments of type StringTemplate. Sounds good to me. In that world, we would probably want a template processor method that takes a StringTemplate and just does obvious, unvetted string concatenation after doing `toString` on each of the expression values. An obvious name for this method is `String.of`. So we would write
String.of(”Hello, \{x}”)
But this is unsatisfying because it is verbose.
I suggest that, rather than having a bit of prefix syntax that allows specification of any template processor, all we really need is a very concise prefix syntax that distinguishes the STR case from all other cases, the assumption being that all other cases do vetting of some sort (else they would just accept strings rather than string templates). That, plus Archie’s recent suggestion that “$” be optional, leads me to suggest the following approach (which I suspect might be a good compromise because I expect that nearly everyone in this discussion will dislike some aspect of it :-) :
—————————
String is not a subtype of StringTemplate; they are disjoint types.
$”foo” is a (trivial) string template literal
“foo” is a string literal
$”Hello, \{x}” is a (nontrivial) string template literal
“Hello, \{x}” is a shorthand (expanded by the compiler) for `String.of($“Hello, \{x}”)`
—————————
Thus you always need “$” to be present before the leading double quote to get a template value. If there is no “$” before the leading double quote, you get a string value. String literals are constant expressions, but if what otherwise looks like a string literal (no leading “$”) contains “\{“, then it is not a constant expression (and if having a constant expression is important to some user, that user should use “+” concatenation instead). We would need to think of a good name for "what otherwise looks like a string literal (no leading “$”) but contains ‘\{‘ “; right now, the best I can think of is “string interpolation literal”—but it isn't really a literal, it’s an expression. Maybe the right terms are:
$”foo” trivial string template expression
“foo” string literal
$”Hello, \{x}” nontrivial string template expression
“Hello, \{x}” string interpolation expression
APIs that need to vet things can provide methods that accept string templates but no methods that accept strings; type checking will then prevent the accident of writing
SQL.process(“INSERT INTO Students (name) VALUES (\{new name});”);
when it should have been
SQL.process($“INSERT INTO Students (name) VALUES (\{new name});”);
(This example is of course borrowed from the explanation of “Little Bobby Tables” over at the Explain XKCD wiki https://www.explainxkcd.com/wiki/index.php/Robert%27);_DROP_TABLE_Students;-- .)
On Mar 13, 2024, at 11:45 AM, Maurizio Cimadamore <maurizio.cimadamore at oracle.com> wrote:
Hi Guy,
On 12/03/2024 17:54, Guy Steele wrote:
(1) avoids this problem by making the syntaxes different. (2b) avoids the problem by making the semantics match. But (2a) totally has this problem.
I agree that 2a leaves us in a place that is suboptimal.
I think 2b is also undesirable (as I explained elsewhere), as it would compromise the design goals of the feature too much IMHO.
So, the choice is (also IMHO) between an ad-hoc conversion (with the problems that I described in my previous email) and a different literal syntax (your (1)).
Maurizio
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-spec-experts/attachments/20240313/423f6fb2/attachment-0001.htm>
More information about the amber-spec-experts
mailing list