Hi
On 15/03/2024 16:07, Guy Steele wrote:
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.
I think the advantage for /not/ 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.
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
Yep, I agreee this a very principled way to look at the problem.
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.)
I think there’s a place for {}. E.g. where {} shines IMHO, is to allow
for /comments/ inside string templates:
|t""" hello this is \{ /* a comment here */ } a commented template """ |
But as a “template” prefix, it’s a bit of a lousy choice. For instance,
one can argue that “1.0” is different from “1”. But there’s only one
place where to look for that “.0”. Whereas, inside a text block, you can
have many different places where the {} ends up. So, while this solves
the problem for compiler writers, {} is not a good solution for us humans.
Maurizio