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