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

​

Reply via email to