<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body style="overflow-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;">
Hi Remi,
<div><br>
</div>
<div>Yes, I think this is a good way to think about the design space. (It is a shame that the fact that this is NOT about string interpolation, but something much more general and focused on security - even though made explicit in the JEP - has been lost in
 some of the wider discussions.)</div>
<div><br>
</div>
<div>You can make the distinction even clearer - reading from the spec - a template "\{x} + \{y}” can be thought of as sugar for the expression new $HiddenClassImplementsStringTemplate(List.of("", " + ", ""), List.of(x, y)). So, sure, it’s an object that has
 the potential to be a string, but it’s an object with a couple of lists in it. The fact that the embedded values are kept as a separate list, and so can be validated and dealt with using domain-specific logic, is the key to safety. You need to write code to
 transform template values into something else (perhaps a string). In the old model, that was the role of the processor (and the reason why they came first - to remind you that the template needed processing to get a value), and with the new model will be a
 method. I agree with you that any design that makes it easy to conflate templates with strings is a road to another 30+ years of injection attacks. </div>
<div><br>
</div>
<div>Gavin</div>
<div><br>
</div>
<div><br>
</div>
<div>
<div>
<blockquote type="cite">
<div>On 16 Mar 2024, at 07:18, Remi Forax <forax@univ-mlv.fr> wrote:</div>
<br class="Apple-interchange-newline">
<div>
<div>
<div style="font-family: arial, helvetica, sans-serif; font-size: 12pt;">
<div><br>
</div>
<div><br>
</div>
<hr id="zwchr" data-marker="__DIVIDER__">
<div data-marker="__HEADERS__">
<blockquote style="border-left-width: 2px; border-left-style: solid; border-left-color: rgb(16, 16, 255); margin-left: 5px; padding-left: 5px; font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica, Arial, sans-serif; font-size: 12pt;">
<b>From: </b>"Maurizio Cimadamore" <maurizio.cimadamore@oracle.com><br>
<b>To: </b>"Guy Steele" <guy.steele@oracle.com><br>
<b>Cc: </b>"amber-spec-experts" <amber-spec-experts@openjdk.org><br>
<b>Sent: </b>Friday, March 15, 2024 5:31:28 PM<br>
<b>Subject: </b>Re: Update on String Templates (JEP 459)<br>
</blockquote>
</div>
<div data-marker="__QUOTED_TEXT__">
<blockquote style="border-left-width: 2px; border-left-style: solid; border-left-color: rgb(16, 16, 255); margin-left: 5px; padding-left: 5px; font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica, Arial, sans-serif; font-size: 12pt;">
<div class="markdown-here-wrapper" style="">
<p style="margin: 0px 0px 1.2em !important;">Hi</p>
<p style="margin: 0px 0px 1.2em !important;">On 15/03/2024 16:07, Guy Steele wrote:</p>
<div class="markdown-here-exclude">
<blockquote cite="mid:942AC667-A175-4F72-9495-684F2FF9236E@oracle.com">
<div>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.</div>
</blockquote>
</div>
<p style="margin: 0px 0px 1.2em !important;">I think the advantage for <em>not</em> 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.</p>
<div class="markdown-here-exclude">
<blockquote cite="mid:942AC667-A175-4F72-9495-684F2FF9236E@oracle.com">
<div><br>
</div>
<div><br>
</div>
<div>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:</div>
<div><br>
</div>
<div>“…”      string literal, must not contain \{…}, type String</div>
<div>$”…”    template literal, may contain \{…}, type StringTemplate</div>
</blockquote>
</div>
<p style="margin: 0px 0px 1.2em !important;">Yep, I agreee this a very principled way to look at the problem.</p>
</div>
</blockquote>
<div><br>
</div>
<div>[...]<br data-mce-bogus="1">
</div>
<div><br data-mce-bogus="1">
</div>
<div>This is how i like to explain the design space to myself.<br data-mce-bogus="1">
</div>
<div>We have two kind of strings, tainted string and untainted string (this is not new, see [1]).<br data-mce-bogus="1">
</div>
<div>An untainted string is a string that can be escaped properly, in our case a StringTemplate. A tainted string is just a String.<br data-mce-bogus="1">
</div>
<div><br data-mce-bogus="1">
</div>
<div>We do not want a String to be a StringTemplate, because it means all untainted strings are tainted strings.<br data-mce-bogus="1">
</div>
<div>We do not want a StringTemplate to be a String, because it means that all tainted strings are untainted strings.<br data-mce-bogus="1">
</div>
<div>So both are different types, with neither a subtype relationship nor an automatic conversion between them.<br data-mce-bogus="1">
</div>
<div><br data-mce-bogus="1">
</div>
<div>For the literals, we need two different constructs otherwise we will have a conversion between tainted and untainted strings,<br>
</div>
<div>we also need the literal to construct an untainted string to be different and upfront to easily distinguish an untainted string from a tainted string, so<br data-mce-bogus="1">
</div>
<div>- "..." constructs a String, a tainted string,<br data-mce-bogus="1">
</div>
<div>- TEMPLATE"..." constructs a StringTemplate, an untainted string.<br data-mce-bogus="1">
</div>
<div><br data-mce-bogus="1">
</div>
<div>About string interpolation, this is another way to create a String and this is not directly related to a string being tainted or not, so it's a kind of orthogonal in term of design.<br data-mce-bogus="1">
</div>
<div>It can not be a prefix like INTERPOLATE, because this is different in nature from TEMPLATE, TEMPLATE creates another kind of String, interpolation creates just a String.<br data-mce-bogus="1">
</div>
<div>Having a static method (a processor) that creates a String from a StringTemplate creates a common conduit to get a tainted string from any untainted strings, which makes the distinction between untainted string and tainted string less relevant. So i would
 advise to not go in that direction.</div>
<div><br data-mce-bogus="1">
</div>
<blockquote style="border-left-width: 2px; border-left-style: solid; border-left-color: rgb(16, 16, 255); margin-left: 5px; padding-left: 5px; font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica, Arial, sans-serif; font-size: 12pt;">
<div class="markdown-here-wrapper" style="">
<p style="margin: 0px 0px 1.2em !important;">Maurizio</p>
<div title="MDH:PHA+SGk8YnI+PC9wPjxkaXYgY2xhc3M9Im1vei1jaXRlLXByZWZpeCI+T24gMTUvMDMvMjAyNCAx
NjowNywgR3V5IFN0ZWVsZSB3cm90ZTo8YnI+PC9kaXY+PGJsb2NrcXVvdGUgdHlwZT0iY2l0ZSIg
Y2l0ZT0ibWlkOjk0MkFDNjY3LUExNzUtNEY3Mi05NDk1LTY4NEYyRkY5MjM2RUBvcmFjbGUuY29t
Ij48ZGl2PlRoZW4gYWdhaW4sIG5vdyB0aGF0IEkgcG9uZGVyIHRoZSBzcGFjZSBvZiB1c2UgY2Fz
ZXMsIGl0IG1heSBiZSAKdGhhdCwgZGVzcGl0ZSBteSBpbml0aWFsIGVudGh1c2lhc20sIGhhdmlu
ZyBhIHNlcGFyYXRlIHN0cmluZyAKaW50ZXJwb2xhdGlvbiBzeW50YXggbWF5IG5vdCBjYXJyeSBp
dHMgd2VpZ2h0IGlmIGl0cyB1c2VzIGFyZSByZWxhdGl2ZWx5CiByYXJlLiBXZSBhbHdheXMgaGF2
ZSB0aGUgb3B0aW9uIG9mIHVzaW5nIGEgc3RyaW5nIHRlbXBsYXRlCiBhbmQgdGhlbiBhcHBseWlu
ZyBhbiBpbnRlcnBvbGF0aW9uIHByb2Nlc3NvciAod2hpY2ggbWlnaHQgYmUgc3BlbGxlZCAKYFN0
cmluZy5vZigmbHQ7dGVtcGxhdGUmZ3Q7KWAgb3IgYCgmbHQ7dGVtcGxhdGUmZ3Q7KS5pbnRlcnBv
bGF0ZSgpYCBvciAKc29tZSBvdGhlciB3YXkpLCBhbmQgYWJvdXQgYWxsIHdlIGxvc2UgZnJvbSB0
aGF0IGFwcHJvYWNoIGlzIHRoZSBhYmlsaXR5CiB0byB1c2Ugc3RyaW5nIGludGVycG9sYXRpb24g
dG8gc3BlY2lmeSBhIGNvbnN0YW50IGV4cHJlc3Npb27igJRmb3IKIHdoaWNoIHdlIHN0aWxsIGhh
dmUgdGhlIG9sZC1mYXNoaW9uZWQgYWx0ZXJuYXRpdmUgb2YgdXNpbmcgYCtgIApjb25jYXRlbmF0
aW9uLiBJZiB3ZSBkcm9wIHN0cmluZyBpbnRlcnBvbGF0aW9uLCB3ZSBjYW4gdGhlbiBkcm9wIHRo
ZSAKSU5URVJQT0xBVElPTiBwcmVmaXgsIGFuZCB3ZSBhcmUgYmFjayB0byBhIHNpbmdsZS1wcmVm
aXggbW9kZWwsIGFuZCB0aGUgCnJlbWFpbmluZyBxdWVzdGlvbiBpcyB3aGV0aGVyIHRoYXQgcHJl
Zml4IGlzIG9wdGlvbmFsLAogYXQgbGVhc3QgaW4gc29tZSBjYXNlcy4gT2theSwgSSB0aGluayBJ
IG5vdyBoYXZlIGEgYmV0dGVyIHVuZGVyc3RhbmRpbmcKIG9mIHRoZSByZWxhdGlvbnNoaXBzIGFt
b25nIHRoZSB2YXJpb3VzIHByb3Bvc2FscyBpbiB0aGUgZGVzaWduIHNwYWNlLiAKVGhhbmtzIGZv
ciB5b3VyIHBhdGllbmNlLjwvZGl2PjwvYmxvY2txdW90ZT5JIHRoaW5rIHRoZSBhZHZhbnRhZ2Ug
Zm9yIF9ub3RfIGhhdmluZyBhIHN0cmluZyBpbnRlcnBvbGF0aW9uIHByZWZpeCwgaXMgdGhhdCB0
aGVuIGludGVycG9sYXRpb24gaXMgImp1c3QgYW5vdGhlciBwcm9jZXNzb3IiIGUuZy4gYSBzdGF0
aWMgbWV0aG9kIHNvbWV3aGVyZSB0aGF0IHRha2VzIGEgc3RyaW5nIHRlbXBsYXRlIGFuZCByZXR1
cm5zIGEgU3RyaW5nLiBBbm90aGVyIFN0cmluZzo6Zm9ybWF0LCBpbiBhIHdheS4gU28gdGhhdCBs
ZWFkcyB0byBhIHJhdGhlciB1bmlmb3JtIGRlc2lnbi48YnI+PGJsb2NrcXVvdGUgdHlwZT0iY2l0
ZSIgY2l0ZT0ibWlkOjk0MkFDNjY3LUExNzUtNEY3Mi05NDk1LTY4NEYyRkY5MjM2RUBvcmFjbGUu
Y29tIj4KPGRpdj48YnI+CjwvZGl2Pgo8ZGl2Pjxicj4KPC9kaXY+CjxkaXY+QW5kIG5vdyB0aGF0
IEkgaGF2ZSB0aGF0IGJldHRlciB1bmRlcnN0YW5kaW5nLCBJIHRoaW5rIEkgbGVhbiAKdG93YXJk
IChhKSBhYmFuZG9uaW5nIHN0cmluZyBpbnRlcnBvbGF0aW9uIGFuZCAoYikgaGF2aW5nIGEgc2lu
Z2xlLCAKc2hvcnQsIF9ub24tb3B0aW9uYWxfIHByZWZpeCBmb3IgdGVtcGxhdGVzICjigJwk4oCd
IHdvdWxkIGJlIGEgcGxhdXNpYmxlIApjaG9pY2UpLCBvbiB0aGUgZ3JvdW5kcyB0aGF0IEkgdGhp
bmsgaXQgbWFrZXMgY29kZSBtb3JlCiByZWFkYWJsZSBpZiB0ZW1wbGF0ZXMgYXJlIGFsd2F5cyBk
aXN0aW5ndWlzaGVkIHVwIGZyb250IGZyb20gCnN0cmluZ3PigJRhbmQgdGhpcyBpcyBlc3BlY2lh
bGx5IGhlbHBmdWwgd2hlbiB0aGUgdGVtcGxhdGVzIGFyZSByYXRoZXIgCmxvbmcgYW5kIGFueSBg
XHtgIHByZXNlbnQgbWlnaHQgYmUgZmFyIGZyb20gdGhlIGJlZ2lubmluZy4gSXQgaGFzIGEgCm1p
bmltYWwgbnVtYmVyIG9mIGNhc2VzIHRvIGV4cGxhaW46PC9kaXY+CjxkaXY+PGJyPgo8L2Rpdj4K
PGRpdj48c3BhbiBjbGFzcz0iQXBwbGUtdGFiLXNwYW4iIHN0eWxlPSJ3aGl0ZS1zcGFjZTpwcmUi
Pjwvc3Bhbj7igJzigKbigJ0gJm5ic3A7ICZuYnNwOyAmbmJzcDtzdHJpbmcgbGl0ZXJhbCwgbXVz
dCBub3QgY29udGFpbiBce+KApn0sIHR5cGUgU3RyaW5nPC9kaXY+CjxkaXY+PHNwYW4gY2xhc3M9
IkFwcGxlLXRhYi1zcGFuIiBzdHlsZT0id2hpdGUtc3BhY2U6cHJlIj48L3NwYW4+JOKAneKApuKA
nSAmbmJzcDsgJm5ic3A7dGVtcGxhdGUgbGl0ZXJhbCwgbWF5IGNvbnRhaW4gXHvigKZ9LCB0eXBl
IFN0cmluZ1RlbXBsYXRlPC9kaXY+PC9ibG9ja3F1b3RlPlllcCwgSSBhZ3JlZWUgdGhpcyBhIHZl
cnkgcHJpbmNpcGxlZCB3YXkgdG8gbG9vayBhdCB0aGUgcHJvYmxlbS48YnI+PGJsb2NrcXVvdGUg
dHlwZT0iY2l0ZSIgY2l0ZT0ibWlkOjk0MkFDNjY3LUExNzUtNEY3Mi05NDk1LTY4NEYyRkY5MjM2
RUBvcmFjbGUuY29tIj4KPGRpdj48YnI+CjwvZGl2Pgo8ZGl2PkkgdGhpbmsgd2UgaGF2ZSBhbGwg
bWFkZSBhbiBob25lc3QgZWZmb3J0IHRvIGV4cGxhaW4gc3RyaW5nIAp0ZW1wbGF0ZXMgYXMgYSBz
aW1wbGUgYW5kIGNsZWFuIHN1cGVyc2V0IG9mIHN0cmluZyBsaXRlcmFscywgYnV0IG5vdyAKdGhh
dCB3ZSBoYXZlIGNvbnNpZGVyZWQgdGhlIHR5cGluZyBhbmQgb3ZlcmxvYWRpbmcgaXNzdWVzLCBt
eSBvcGluaW9uIGlzCiB0aGF0IGl0IGp1c3QgaXNu4oCZdCBwb3NzaWJsZSB3aXRob3V0IHNvbWUg
YW1vdW50IG9mCiB1bndhbnRlZCBjb21wbGljYXRpb24uIFN0cmluZ3MgYW5kIHN0cmluZyB0ZW1w
bGF0ZXMgYXJlIGp1c3QgZGlmZmVyZW50IApiZWFzdHMsIGFuZCB3ZSB3b3VsZCBkbyB3ZWxsIHRv
IG1haW50YWluIHRoYXQgZGlzdGluY3Rpb24gcmF0aGVyIHRoYW4gCnRyeWluZyB0byBjb25mbGF0
ZSB0aGVtLiBZZXMsIHJlcXVpcmluZyBhIHByZWZpeCBvbiB0ZW1wbGF0ZXMgd291bGQgCmltcG9z
ZSBhIHNtYWxsIGNvc3TigJRwZXJoYXBzIHdlIHNob3VsZCByZWdhcmQgaXQKIGFzIGEgInN5bi10
YXgiIHJhdGhlciB0aGFuIGEg4oCcY292ZXIgY2hhcmdl4oCd4oCUb24gZXZlcnkgdGVtcGxhdGUg
d2Ugd3JpdGUsCiBidXQgSSBqdWRnZSB0aGF0IGNvc3Qgd2VsbCB3b3J0aCBpdCBmb3IgdGhlIHJl
YWRhYmlsaXR5IGl0IHdvdWxkIGJ1eS48L2Rpdj4KPGRpdj48YnI+CjwvZGl2Pgo8ZGl2PihCeSB0
aGUgd2F5LCBJIGFwcHJlY2lhdGUgSm9obuKAmXMgc3VnZ2VzdGlvbiBvZiBhbGxvd2luZyBhIHRl
bXBsYXRlIAp0byBiZWdpbiB3aXRoICZuYnNwO+KAnFx7fSAsIGJ1dCB0aGlzIHN0cmlrZXMgbWUg
YXMga2luZCBvZiBhIGhhY2sgcmF0aGVyIHRoYW4gYQogbmF0dXJhbCB1c2Ugb2YgdGhlIFx74oCm
fSBzeW50YXguIEEgZGlzdGluY3RpdmUgc2luZ2xlLWNoYXJhY3RlciBwcmVmaXggCndvdWxkIGJl
IGJldHRlci4pPC9kaXY+PC9ibG9ja3F1b3RlPkkgdGhpbmsgdGhlcmUncyBhIHBsYWNlIGZvciBc
e30uIEUuZy4gd2hlcmUgXHt9IHNoaW5lcyBJTUhPLCBpcyB0byBhbGxvdyBmb3IgX2NvbW1lbnRz
XyBpbnNpZGUgc3RyaW5nIHRlbXBsYXRlczo8YnI+PGJyPmBgYGphdmE8YnI+dCIiIjxicj7CoMKg
IGhlbGxvPGJyPsKgwqAgdGhpcyBpczxicj7CoMKgIFx7IC8qIGEgY29tbWVudCBoZXJlICovIH08
YnI+wqAgYSBjb21tZW50ZWQ8YnI+wqAgdGVtcGxhdGU8YnI+IiIiPGJyPjxwPmBgYDwvcD48cD5C
dXQgYXMgYSAidGVtcGxhdGUiIHByZWZpeCwgaXQncyBhIGJpdCBvZiBhIGxvdXN5IGNob2ljZS4g
Rm9yIGluc3RhbmNlLCBvbmUgY2FuIGFyZ3VlIHRoYXQgIjEuMCIgaXMgZGlmZmVyZW50IGZyb20g
IjEiLiBCdXQgdGhlcmUncyBvbmx5IG9uZSBwbGFjZSB3aGVyZSB0byBsb29rIGZvciB0aGF0ICIu
MCIuIFdoZXJlYXMsIGluc2lkZSBhIHRleHQgYmxvY2ssIHlvdSBjYW4gaGF2ZSBtYW55IGRpZmZl
cmVudCBwbGFjZXMgd2hlcmUgdGhlIFx7fSBlbmRzIHVwLiBTbywgd2hpbGUgdGhpcyBzb2x2ZXMg
dGhlIHByb2JsZW0gZm9yIGNvbXBpbGVyIHdyaXRlcnMsIFx7fSBpcyBub3QgYSBnb29kIHNvbHV0
aW9uIGZvciB1cyBodW1hbnMuPC9wPjxwPk1hdXJpemlvPGJyPjwvcD4=" style="height:0;width:0;max-height:0;max-width:0;overflow:hidden;font-size:0em;padding:0;margin:0;">
​</div>
</div>
</blockquote>
<div><br>
</div>
<div>Rémi<br data-mce-bogus="1">
</div>
<div><br data-mce-bogus="1">
</div>
<div>[1] <a href="https://en.wikipedia.org/wiki/Taint_checking">https://en.wikipedia.org/wiki/Taint_checking</a><br data-mce-bogus="1">
</div>
<div><br data-mce-bogus="1">
</div>
</div>
</div>
</div>
</div>
</blockquote>
</div>
<br>
</div>
</body>
</html>