[string-templates] Accidental use of StringTemplate instead of string

Jim Laskey james.laskey at oracle.com
Thu Oct 20 16:15:10 UTC 2022


> On Oct 20, 2022, at 11:44 AM, Tagir Valeev <amaembo at gmail.com> wrote:
> Hello!
> As stated in JEP 430 text, the string template is a well-formed
> expression of StringTemplate type. Also, toString() method of
> StringTemplate prints a debug-friendly representation like
> [fragments](values) which is not intended for actual use. I can
> imagine that the following mistake may happen often, especially by
> inexperienced developers, or developers with background in other
> languages:
> int x = 10, y = 20;
> System.out.println("\{x} plus \{y} equals \{x + y}");
> Output expected by programmer: 10 plus 20 equals 30
> Actual output (successfully compilable): ["", " plus ", " equals ",
> ""](10, 20, 30)
> As an IDE vendor, we can surely provide an inspection for some
> well-known methods like PrintStream#println(Object) with a quick-fix
> to add a STR. prefix. However, not everybody uses IDEs. Probably the
> language itself could help here somehow? E.g., uses of StringTemplate
> where the Object type is expected might trigger a warning. This is
> similar to array toString(), and every static analyzer has an
> inspection about this. Honestly, I don't know a good solution but I
> feel that it's not a good idea to introduce a new error-prone
> construct, which is compilable and runnable, could be mistakenly used
> and doesn't make sense.

There was some discussion early on about overloading print/println/format (StringBuilder::append) with an StringTemplate argument that would internally do the (optimal) interpolation. If I remember correctly, the discussion digressed into what was "least surprise”. 

The problem here is we can’t have it both ways. If we treat it “like a string” in these cases then user will expect it to be a “like a string” everywhere.

Another option would have been to make StringTemplate::toString generate UnsupportedOperationException, which would cause havoc for debuggers.

As always, we are open to suggestions, but I think this is one of those cases where users “learn” to do the right thing.

BTW: I’ll add “StringTemplate” to the front of the toString.

> As we are here, is it planned to specify StringTemplate equals and
> hashCode? It's naturally a tuple of (fragments, values) lists, so
> equals and hashCode could be defined.

This is something I slipped up on and has been mentioned by others. I will add.

> Also, current draft [1] suggests
> that this is a non-sealed interface. Is it really intended to allow
> third-party implementations?

Two reasons for this, primary is that the compiler generates non-uniform classes to represent StringTemplates. Secondarily there is an opportunity for other languages to map templates from their language.

Also, if a user wants to implement promise-like templates read from files or use ${} syntax in strings with values come from maps or enumerations, then they are free to do so.

> Sorry if these questions were already discussed, I might skip some
> discussions. I would be happy to see the pointers to previous
> discussions.

Comments are always welcome. There has been little discussion here, but here is the place. BTW: I can discuss parsing patterns when you are ready.

> With best regards,
> Tagir Valeev
> [1] http://cr.openjdk.java.net/~jlaskey/templates/docs/api/java.base/java/lang/template/StringTemplate.html


— Jim

More information about the amber-spec-experts mailing list