On Mar 15, 2024, at 5:56 AM, Maurizio Cimadamore 
<[email protected]> wrote:On 15/03/2024 02:10, Guy Steele wrote:
Oh, I think I get it now; I misinterpreted "The compiler might require a prefix 
here” to mean "The compiler might require a prefix on a literal that is a 
method argument”, but I now see, from your later sentence "Basically, requiring 
all literals that have embedded expression to have a prefix . . .” that maybe 
you just want to adjust the syntax of literals to be roughly what Clement 
suggested:

“…”                             plain string literal, cannot contain \{…}, type 
is String
INTERPOLATION”…”     string interpolation, may contain \{…}, type is String
TEMPLATE”…”      string template, , may contain \{…}, type is StringTemplate

where the precise syntax for the prefixed INTERPOLATION and TEMPLATE is to be 
determined. Do I understand your proposal correctly now?
Yes, with the further tweak that the prefix (with syntax TBD) might be omitted 
in the "obvious cases" (but kept for clarity):

* "Hello" w/o prefix is just String
* "Hello \{world}" without prefix is just StringTemplate

Does this help? (I'm basically trying to get to a world where use of prefix 
will be relatively rare, as common cases have the right defaults).

Yes, this helps immensely.

So in the model you suggest, string templates would mostly not need prefixes, 
but in the example I raised where one might foresee editing templates so as to 
cross into or out of the edge case of zero template expressions, I could 
choose, if I wish, to write

SQL.process(TEMPLATE”CREATE TABLE foo;”);
SQL.process(TEMPLATE”ALTER TABLE foo ADD name varchar(40);”);
SQL.process(TEMPLATE”ALTER TABLE foo ADD title varchar(30);”);
SQL.process(TEMPLATE”INSERT INTO foo (name, title) VALUES (‘Guy’, ‘Hacker’);”);
SQL.process(TEMPLATE”INSERT INTO foo (name, title) VALUES (\{other name}, 
\{other
job});”);

rather than

SQL.process(”CREATE TABLE foo;”);
SQL.process(”ALTER TABLE foo ADD name varchar(40);”);
SQL.process(”ALTER TABLE foo ADD title varchar(30);”);
SQL.process(”INSERT INTO foo (name, title) VALUES (‘Guy’, ‘Hacker’);”);
SQL.process(TEMPLATE”INSERT INTO foo (name, title) VALUES (\{other name}, 
\{other
job});”);

That makes sense to me in this two-prefix model.

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.


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

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.

(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.)

—Guy


Reply via email to