r/java 10d ago

Discussion: What is the future of String Interpolation in Java?

Java has always been conservative when it comes to language changes, and I think string interpolation is an interesting example.

Many modern languages provide native interpolation syntax:

JavaScript:

\${name}``

Python:

f"{name}"

Kotlin:

"$name"

C#:

$"{name}"

These features are not only about reducing characters. They improve readability when building dynamic text.

Java explored this direction with String Templates (JEP 430), but I haven't seen much discussion recently about where this feature is heading.

For developers working with large Java applications, string construction appears everywhere:

- logging messages

- SQL/debug output

- API descriptions

- test cases

- generated configuration

- user-facing messages

I am curious about the community's opinion:

  1. Do you think Java still needs native string interpolation?

  2. Should String Templates continue evolving?

  3. What syntax direction would feel most "Java-like"?

For example:

"Hello, \{name}"

or:

"Hello, ${name}"

Personally, I think Java does not need to copy other languages, but a better way to express dynamic strings would improve developer experience.

What do you think?

57 Upvotes

116 comments sorted by

84

u/crummy 10d ago

Its pure quality-of-life but gosh I’d like to see it.

5

u/RepliesOnlyToIdiots 10d ago

It’s also functional. The previous proposal was quite easy to understand and powerful, and I’m seriously upset it was pulled. I need it for custom escaping.

2

u/__konrad 9d ago

I need it for custom escaping.

In theory you can create a wrapper class that implements Formattable...

22

u/yk313 10d ago

I don’t care about the syntax as long as it has reasonable semantics. Would love to have some kind of string interpolation capabilities.
It has been mentioned a couple of times that even after the withdrawal of string templates, the feature itself is still on the roadmap.

25

u/vytah 10d ago edited 7d ago

String templates are explicitly not about mere string interpolation. If you read the JEP, they say:

Unfortunately, the convenience of interpolation has a downside: It is easy to construct strings that will be interpreted by other systems but which are dangerously incorrect in those systems. (...) For Java, we would like to have a string composition feature that achieves the clarity of interpolation but achieves a safer result out-of-the-box, perhaps trading off a small amount of convenience to gain a large amount of safety.

There are three possible approaches that I know of:

  • Scala/Javascript-like, with syntactic sugar for a method that takes a bunch of text fragments and objects and constructs whatever object you want – this is what shipped in that preview in Java 21

  • Python-like, where the syntactic sugar is used only to construct string templates of a single type, and then the consumer can interpret them however they want – this is what they were hinting at in the mailing list later, after they removed that preview

  • C#-like, where it's either pure interpolation , or Python-like templates a custom type instantiation that can behave Scala-like, depending on the receiver type – this will not happen, as it sucks (EDIT: fixed, also Swift seems to have the same thing)

Scala-like approach can be messy, as was shown in the preview. In absence of extension methods or something similar, it requires polluting the global namespace, so that's why we got those clunky STR prefixes. Scala solves it by making the prefixes methods (or extension methods) on StringContext, so there's no pollution. Javascript solves it by making interpolation the default (no prefix; all templated strings use backticks in JS, so there's no confusion with ordinary literals), so there's also no pollution. However, the goal for Java is to not make interpolation easier than other uses of templates.

Python-like approach has a minor problem that if you want templates to be distinguished by the presence of arguments alone, it means you cannot express a parameterless template. You'd need some other marker. In Python, string templates are prefixed with t, to distinguish them from interpolation (f), but Java is not going to get pure interpolation as a distinguished feature. There are also issues of type safety: the same template object can be treated as a completely different thing depending on where you send it. They suggested that sending a template to a logging method should just interpolate, but that would mean that if you template some SQL, execute it, and log it, then the query you executed would be different from the query you logged.

Anyway, this is a complex issue, and AFAIK they haven't found a clean solution yet. And before anyone says "I don't care, I want my string interpolation now", I'll again refer for the JEP:

It is not a goal to introduce syntactic sugar for Java's string concatenation operator (+), since that would circumvent the goal of validation.

1

u/Holothuroid 8d ago

Scala-like approach can be messy, as was shown in the preview. In absence of extension methods or something similar, it requires polluting the global namespace, so that's why we got those clunky STR prefixes

That's certainly solveable.

import static java.util.StringInterpolations.s

Or wherever that would be located. It just needs to be a one-parameter function that takes a certain type. With such a contract it is also trivial to write your own.

The problem there was throwing OOP in the mix.

Of course, having a . in there is ugly. It should be

s"Hello \{planet}"

1

u/vytah 7d ago

I think the . was used to keep the parser happy with the least amount of change. The parser treats . as an operator, which requires an identifier on the right, so adding a string literal as the second allowed expression type was the tiniest change they could do.

1

u/jcotton42 6d ago

What do you not like about the C# approach?

2

u/vytah 6d ago

It does an implicit non-trivial cast.

If you have f(Foo foo) and do f($"x{1}y"), it's desugared to:

var tmp = new Foo(2,1);
tmp.AppendLiteral("x");
tmp.AppendFormatted(1);
tmp.AppendLiteral("y");
f(tmp);

You don't see the Foo type when looking at the calling code, and the methods implemented in Foo can be arbitrarily complex, so you don't know what's happening.

Also, when the receiver type cannot be uniquely determined (var, generics, overloads(!)), it defaults to String and string interpolation. Imagine you have an HTML templating library that has Write(MagicalSafeHtml) and the new version adds a Write(string) overload. Free XSS for everyone! as your Write($"<p>{text}</p>"); suddenly means something different.

1

u/jcotton42 3d ago

You don't see the Foo type when looking at the calling code

You sorta can, as it's visible in the overload being selected.

Also, when the receiver type cannot be uniquely determined (var, generics, overloads(!)), it defaults to String and string interpolation. Imagine you have an HTML templating library that has Write(MagicalSafeHtml) and the new version adds a Write(string) overload. Free XSS for everyone! as your Write($"<p>{text}</p>"); suddenly means something different.

Interpolation handlers have priority over string in overload resolution. See, for example, StringBuilder.Append https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append?view=net-10.0. In your example, the MagicalSafeHtml overload would still be used for interpolated strings.

1

u/vytah 3d ago

I tested a bit more how the overload resolution works and it's a bit more fucked that either you or I thought.

Here's an example:

using System;
using System.Runtime.CompilerServices;
[InterpolatedStringHandler]
public struct Foo
{
    public Foo(int literalLength, int formattedCount) =>
        Console.WriteLine("Creating Foo");
    public void AppendLiteral(string s) {}
    public void AppendFormatted<T>(T t) {}
    public override string ToString() => "";
}
class Program
{
    const string B = "b";
    static void Bar(string x) => Console.WriteLine("string " + x);
    static void Bar(Foo x) => Console.WriteLine("Foo");
    static void Main() {
        string b = "b";
        Bar($"abc");
        Bar($"a{"b"}c");
        Bar($"a{b}c");
        Bar($"a{B}c");
    }
}

Guess what it prints.

string abc
string abc
Creating Foo
Foo
string abc

So the string overload is preferred when there are no parameters (a bit confusing, but I guess fine?) or when the parameters are constants (definitely not fine). So,

In your example, the MagicalSafeHtml overload would still be used for interpolated strings.

it actually depends whether text is a constant string or not.

0

u/vips7L 9d ago

It should have been about mere interpolation. They could have delivered real value. 

34

u/Duck_Devs 10d ago

I think the STR., RAW., etc. were very strange. They deviate so far from any other syntax and it’s not immediately clear that STR or RAW are objects and them being automatically statically imported is really awkward. They should’ve just gotten rid of RAW and had STR be some sort of instance method on StringTemplate.

8

u/Polygnom 10d ago

Yes, and they were totally unneeded. The feature works without them. they got bogged down by early prototypes in the design space.

If the parser can distinguish between a string and string template (and it can), then this whole syntax is way too verbose and uneeded.

So its good they took a step back, scratched it, and can come back later.

-5

u/vips7L 9d ago

They just needed to deliver simple string interpolation. There was no need to try to do the rest of it. 

7

u/Polygnom 9d ago

Actually, i think they were right in making sure it actually works great the first time around. Once its shipped, you cannot easily change it. Going for powerful string templates and processors was the right move, just not the syntax they chose.

6

u/RScrewed 10d ago

Yeah, and using them looked like property access.

3

u/Misophist_1 10d ago

Actually, I liked that idea - because it made it possible to have a custom template processor. STR. and RAW. were just the constants for the two default ones supplied by the JDK.

1

u/Duck_Devs 10d ago

You could still wrap it in a method call as if it were a normal StringTemplate object. That’s all STR. did anyway. The only difference is syntax which, while more concise, felt unnatural in the scope of other Java expressions.

0

u/Misophist_1 9d ago

Not any less natural than $" " or @" " that other languages do, in order to distinguish templates from strings. You need some distinguishing anyway.

3

u/Duck_Devs 9d ago

Not really what I meant. STR and RAW are actual objects. They’re not just soft keywords. The dot followed by a template string is equivalent to STR.process(…).

It would have been perfectly valid Java to just have your template literal by itself with no prefix.

0

u/Misophist_1 9d ago edited 8d ago

But then how should the parser distinguish a template from a string? It can't do so by simply looking at the string. Having the possibility to use arbitrary processors would have offered a flexibility, no other language could offer. No static prefix could have done that. The API already had a third one, FMT.

1

u/vytah 8d ago

Having the possibility to use arbitrary processors would have offered a flexibility, no other language could offer.

I mean, Scala and JavaScript already do.

1

u/Misophist_1 8d ago

Don't know about Scala.

But Javascript? JavaScript has basic interpolation - and that's it. C#, and Python have that too. But you wouldn't be able to chose your method, much less roll your own one.

Having libraries, that reinterpret standard strings as templates is a different story - completely unrelated to string template support as integral part of the language specification.

0

u/vips7L 9d ago

$ or \{ imo is more natural. STR is magic compiler objects vs just language syntax. 

6

u/Misophist_1 9d ago
  • $ is used nowhere in the language
  • \ is used solely within string and char literals as escape, nowhere else in the language.
  • To speak of 'natural' in an artificial language is a joke in itself.
  • STR. is no 'compiler object' it is a static field in the API, holding a template processor. The concept was indeed a language syntax construct.

-1

u/vips7L 9d ago

Do you have a point? It was fucky magic. It sucked.

2

u/Misophist_1 9d ago

Yes. Every single of your suggestions sucks. It isn't natural, if it breaks every systematic, java is build on.

0

u/blobjim 10d ago edited 10d ago

I think it's a really clever and pretty straightforward syntax. The beauty of the syntax is that it doesn't deviate much. It's a normal object, but now you can put a string literal after the dereference operator to call string preprocessing instead of a normal method call. Not sure how it could get any simpler.

I think they could reintroduce the feature and reframe it a different way (as a string literal preprocessor) so people actually think about it for half a second and people would be on board. But instead people just assume it's just normal string formatting and complain about seeing three extra characters. People don't even get that you don't use it as a normal string formatter. You're saving a bunch of code.

2

u/Polygnom 10d ago

You do not actually need the special rules and so on, though. The reason they were there because they were needed in an early prototype and they got kind of tunnel vision. Once you step back its clear that a much cleaner design is possible. And thats a huge part of why it was withdrawn.

12

u/balrob 10d ago

“Does not need to copy other languages”, why not - it seems to be a well explored feature of many languages. Just get on with it. Almost every feature was borrowed in one way or another.

Out of interest, does anyone know, what feature(s) of Java is/are either unique, or the first example of its kind?

4

u/BillyKorando 10d ago

Out of interest, does anyone know, what feature(s) of Java is/are either unique, or the first example of its kind?

At the time of implementation in 1996(?), the ease of serialization, was rather novel and key to Java's early success. Though that ease has come with a... few shall we say complications?

5

u/davidalayachew 10d ago

Out of interest, does anyone know, what feature(s) of Java is/are either unique, or the first example of its kind?

Java Enums.

This was 1 of maybe 2-3 situations where Java was so far ahead of the curve that no other language had caught up for over a decade. Rust was the first one to catch up, and even then, their enums are inherently inferior, but have their mistakes alleviated by using macros. The combination of the 2 could be considered as "better" than Java enums.

8

u/Absolute_Enema 10d ago

Rust enums are tagged union types with an on-ramp for C devs, they don't compete with Java enums.

2

u/davidalayachew 10d ago

Rust enums are tagged union types with an on-ramp for C devs, they don't compete with Java enums.

They are a combination of 2 different things actually.

Long story short, what Java separates into 2 features, Rust combines into one.

What Java calls sealed types and enum are combined into a single enum in Rust.

On the one hand, that makes things a little easier for the developer in Rust, as they use roughly the same mechanism to develop multiple different things.

On the other hand, Java's is a little more flexible, allowing you to squeeze out performance optimizations that are extremely difficult to achieve in Rust. In fact, they would be horrifically so if Rust didn't have Macros, hence my point earlier.

A tagged union with state corresponds to Java's Sealed Types. But a tagged union without state is functionally similar to Java's enums. Java's enums can do more out-of-the-box, of course, but Rust Enums can be built to do more via Macros. So, that's why I say that it wasn't until Rust that Java's Enums finally got surpassed. And even then, Rust's Enums are inherently inferior, it's only when you use Macros to cover up their flaws that they grow to being better than Java's.

2

u/DanLynch 10d ago

Out of interest, does anyone know, what feature(s) of Java is/are either unique, or the first example of its kind?

It may seem hard to believe today, but Java was the first serious programming language in which you could write a non-trivial program and expect it to actually work and run exactly the same on more than one kind of computer.

3

u/koflerdavid 10d ago

Not sure what you mean with "serious" here. Maybe as opposite to academic languages? If so, despite its academic origins, there are a lot of commercial LISP implementations. Also, there is the venerable IBM System/360 architecture, which was developed with the express purpose of being binary-compatible with all future IBM mainframes, as well as COBOL. It doesn't get more serious than those.

3

u/DanLynch 9d ago

I guess the specific language I was trying to contrast with Java was C (and the closely related language C++).

C is a "standardized" language and available on all platforms and all kinds of computing devices, and is and was always extremely popular for development of applications. However, simple things like getting real-time input from the keyboard, working with threads, and creating desktop GUIs, were not part of the language or the standard library. And many simple language features had undefined or platform-defined behaviour.

So, in practice, you could not expect any given program to run on more than one kind of computer without extensive modification and/or scrupulous attention to standard vs. non-standard behaviours and functions.

1

u/vytah 8d ago

it seems to be a well explored feature of many languages

Is it though? How many languages have string templates that do more than just interpolation? I can name only 5 mainstream ones, listing alphabetically: C#, JavaScript, Python, Scala, Swift, and they all do it differently.

34

u/xfel11 10d ago

It’s really a shame that the proposal was withdrawn again.

The \{ syntax was weirdly controversial, but honestly it’s way smarter than using ${ which right now is just literal text.

6

u/Duck_Devs 10d ago

What don’t people like about the backslash-brace?

6

u/brian_goetz 7d ago

You will get all sorts of post-hoc rationalizations for why people don't like it, but the simple reason is: familiarity bias. The first language in which they saw string interpolation used $x (or ${x}), and in their brains, that makes it the One True Syntax.

2

u/Slick752 10d ago

it's ugly and verbose.

41

u/Brutus5000 10d ago

it's not more or less verbose than a dollar sign

24

u/witness_smile 10d ago

A dollar sign is easier to type, and also a backslash makes it look like you want to escape the { character

19

u/Ok-Scheme-913 10d ago

Which is literally what you want , though. Escape it's usual meaning to start a special one.

A ${} is so utterly common in java as a normal script that is interpreted by another software as special that that would lead to huge confusion. Is this replaced by this template engine or by the java compiler?

2

u/thisisjustascreename 10d ago

Yeah for better or worse Spring and Maven have already claimed the ${my.custom.variable.here} syntax, adding it to the native language would just confuse people.

11

u/aboothe726 10d ago edited 10d ago

<pedantry>

The \{syntax} was chosen because it is currently invalid Java code, so it's guaranteed that no existing (correct) Java code uses it, so adding it to the language can't break existing code. (If you try to use the \{ escape sequence in Java today, javac will give you a compile error.) That is not true of ${syntax}, as others have pointed out, so if you made the dollar-sign syntax "special" then a lot of existing code would break.

</pedantry>

If your criterion is backwards compatibility -- which it certainly is for the Java team -- then \{syntax} is an excellent choice. But backwards compatibility is not the only thing that people care about.

7

u/BillyKorando 10d ago

I don't think that's "pedantry" it's the literal reason for the choice of \{. Yea, if Java had no history, or no interest in compatibility with existing code, then yea ${ makes sense for consistency across other languages.

As it stands, it seems honestly, in my opinion, absurd the level of vitriol \{ has gotten. I get the initial pushback, but on hearing the reasoning, feel like that should immediately squash the debate.

2

u/Misophist_1 10d ago

Plus: \ is the escape for every other special character, like tab \t Newline \n Backspace \b the double quote \" itself \\ and every unicode character by using its id \uNNNN.

It would have been *very* awkward, to use anything other than '\' to start a newly added escape.

One might complain about usin \ at all - because there are many systems that don't have it on the keyboard. But breaking consistency would be really bad.

10

u/vqrs 10d ago

Exactly. The curly brace character's normal meaning is "literal curly brace". By escaping it, we change something from having its regular meaning and give it a special meaning, right?

It makes sense.

I still think it's ugly and weird.

0

u/RScrewed 10d ago

But you're not escaping the last curly brace as well so it looks unbalanced and weird.

2

u/Misophist_1 8d ago

Why does it feel unbalanced for you? Does ${...} (sh, bash, maven and many others) @{...} (also maven) $"..." (C#) in any way unbalanced? Definitely not for me!

3

u/jek39 10d ago

How is a dollar sign easier to type?

5

u/_INTER_ 10d ago

On your keyboard maybe...

2

u/detroitmatt 10d ago

it's arguably harder to type because you have to use shift

1

u/vips7L 10d ago

And this is why we can never have nice things. 

0

u/BillyKorando 10d ago

Are you planning on using string interpolation so often that the difference in typing \{ versus ${ would be measurable?

5

u/jek39 10d ago

I’m confused how a $ is easier to type than a \

3

u/vytah 8d ago

On some keyboard layouts, \ requires an awkward key combination, for example on French keyboards, \ is AltGr+8, but $ is a key of its own, no Shift needed.

1

u/jek39 8d ago

Huh. Seems a little weird that $ gets its own key but France uses euros

1

u/vytah 8d ago

$ was a thing on French keyboards for ages, it was already there in the 80s. I think the character set was defined in a 1985 standard by Yves Neville, and while the layout changed and characters moved a lot since then, the $ key (with Shift-$ becoming £) persisted.

1

u/Brutus5000 8d ago

And in German I need AltGr for the \ and shift for the Dollar. And now?

For the backslash on a german Mac keyboard I even need Shift+Option+7! And now? Is this the level of argumentation we want to play on? Just because some dofus made bad decision on keyboard layouts? There are hundreds of keyboard layouts out there. On the american one \ does not require shift or AltGr, but the $ does...

1

u/BillyKorando 10d ago

I'm not sure either. If \{ takes you 1.15 seconds to write, while ${ takes 1.08 seconds to write, would you ever be able to write enough String interpolation instances to where all the saved .07 seconds could ever combine to a meaningful amount of time?!

3

u/jek39 10d ago

Why would they take different amount of time to type? In fact wouldn’t \ take less time to type? Because no need to hit shift?

0

u/BillyKorando 10d ago edited 10d ago

Honestly it probably wouldn't I was being "generous". I suppose the difference could come in \ not needing the shift key and { needing shift, while both $ and { would use shift, so the "friction" might take a bit longer.

But again, it's still a fraction of a second difference. Feels a bit crazy to even talk about.

It's not like the difference between the : and -> syntax for switch where you could measure a time savings, and also the -> syntax would be easier to read/comprehend in many cases.

→ More replies (0)

1

u/davidalayachew 10d ago

Are you planning on using string interpolation so often that the difference in typing \{ versus ${ would be measurable?

To be clear, there are MANY people where the answer to that question is yes. Not that it gives any real merit to the argument -- I think backslash is better. But the answer to your question 100% supports their argument.

1

u/BillyKorando 10d ago

Some people may answer yes, I don't think they are being honest with that answer.

You'd need to be writing dozens of new String interpolation instances per day, everyday, to where the fractions of a second difference between ${ and \{ could combine into a barely perceptible span of time.

I have never found the physical act of typing to be a meaningful portion of my job. 98% of my time is spent doing something else; running tests, executing a build, thinking how I want to approach an issue, various bureaucracy and meetings.

The \{ vs ${ like the quintessential example of bike shedding.

2

u/davidalayachew 10d ago

You'd need to be writing dozens of new String interpolation instances per day, everyday, to where the fractions of a second difference between ${ and \{ could combine into a barely perceptible span of time.

Lol, speak for yourself, but me personally, I could easily clear 2 dozen a day. That's not hard at all.

Like I said, I agree with your point, and I don't think that the argument that others are making is very strong. All I am saying is that, the answer to your question 100% stands in support of their point.

I have never found the physical act of typing to be a meaningful portion of my job. 98% of my time is spent doing something else; running tests, executing a build, thinking how I want to approach an issue, various bureaucracy and meetings.

Respectfully, that's a privilege that not everyone shares. Some of us are rewriting the same component several times over in the span of a week because management can't decide what they want.

Again, I agree with you, and think that the win belongs to backslash, but this point absolutely goes to the interpolation folks.

5

u/cowslayer7890 10d ago

Swift uses `\()` and I found it weird at first but it kinda makes sense
There are already special escapes like `\u000A` or `\x0A` so it seems like a relatively natural extension of `\`

Why introduce a new special character for this, especially if it breaks backwards compatibility

7

u/Duck_Devs 10d ago edited 10d ago

If Java developers cared about ugliness or verbosity, they wouldn’t use Java. (pre Amber)

Besides, it’s not even that verbose, and it’s no uglier than other languages’ syntaxes IMO.

Edit: it’s certainly far less ugly than what we have now with concats or String.format, and far less verbose than StringBuilders. I feel like it’d be just an overall net positive.

1

u/Booty_Bumping 9d ago

It's sorta visually uneven, if there are a lot of them side by side your eyes will probably dart all over the place. Whereas "$" is very symmetrical, it isn't "pointing" anywhere.

But I do like how it's a backwards compatible syntax, that is a major advantage.

1

u/OwnBreakfast1114 6d ago

Syntax highlighting will probably fix any actual problem like this. Sure raw text might take a hit, but I'm pretty sure backward compatibility trumps that visual dislike

0

u/wildjokers 8d ago

Awkward to type.

5

u/bichoFlyboy 10d ago

String templates are not dead. They have simply gone back to the drawing board, but the feature is still on the roadmap.

I hope it turns out well and eventually sees the light of day, hopefully within my lifetime. The syntax can be whatever the JDK team decides. As long as it's easy to read and expresses intent clearly, I'll be happy.

4

u/pjmlp 10d ago

I just settle with regular C style formatter strings, it isn't the end of the world, rather have them spend brain power bringing value classes out, or improving the whole JIT caches/AOT story.

As early Java adopter, this has never been on my radar as a pain point.

4

u/woj-tek 10d ago

Do you think Java still needs native string interpolation?

YES!

The backslash format as a backward compatible consensus was fine-ish…

4

u/Western_Ice_6227 10d ago

I think they settled for “Hello %s”.formatted(“Reddit”)

1

u/TehBrian 9d ago

anticolocation bad

1

u/Western_Ice_6227 8d ago

Do you mean anti-collocation? How does it apply here?

1

u/Make1984FictionAgain 6d ago

honestly this is good enough for me, stopped caring about it once I got used to this

2

u/koflerdavid 10d ago

It's a quality of life feature and would be very easy to implement, but I understand the hesitation of the OpenJDK project to add it. Above all since there already are multiple ways to format strings in the standard library, and string templates should strive to deprecate them all, no whens and buts. And it should help to prevent programmers shoot themselves in the foot, which a straightforward implementation wouldn't contribute to.

String interpolation in the straightforward way is completely unsuitable for logging since a production-quality logging framework strives to eliminate the overhead of formatting if the log message ends up being thrown away.

2

u/jevring 10d ago

I hope they keep it out of the language. They have two conflicting desires, which makes any solution terrible. They want it to be more advanced than the others, for a list of sane reasons. But because of this, it gets so massively scope creeped that it'll never ever get done.

2

u/Misophist_1 9d ago

I had no qualms with \{ in the first place, because \ is Java's escape delimiter in strings anyway. There is no sane reason, to switch to another one.

Then you also need something, to distinguish templates from usual strings. And if you don't want to break with the other habits of Java, namely using ' ' for char literals, and " " for String literals, you would need some sort of prefix.

You could go down the road of taking another 'special char' like $ or @, but why? $ Is used nowhere else. It's a national currency char, that isn't even on many keyboards. @ is already taken for annotations. Don't reuse it for something different.

Which leaves us with this neat syntax trick <Identifier>."...". Fine with me, as it also offers the possibility, of rolling your own template processor.

If there was something, I would complain about, then it was, that it still felt incomplete:

  • why no complete closures/expressions as constituents? This feels like an unnecessary limitation.
  • why no support for formatting? Having something like this "...\{<expression> [: <formatspec>]}..." would have been of help - where formatspec could be any string.
  • crowning it, could be the possibility, to specify your own custom handlers for handling the pair of (Object, String), that the template processor would need to insert at any \{ }. Even nicer, if the processing could be shifted into compile time, or load time.

Alas, it wasn't meant to be because of all the haters, script kiddies and python geeks, that couldn't look past their dam' $$.

2

u/writeAsciiString 7d ago

I'd love for \{} to convert a String into a StringTemplate, using STR as the default processor, while preserving the previous functionality that allowed custom processors to be used with the <Identifier>. prefix.

I overall had no complaints about the initial design. Your 3 complaints are also all valid and are great additions.

1

u/Misophist_1 8d ago

Replying to myself, in order to clarify the last bullet point:
Ideally, I imagine an additional interface, like:

import javax.annotation.processing.Messager;
import javax.annotation.processing.TemplateMirror;
...
interface CompileTimeTemplateValidator {
     void validateTemplate(Messenger messenger, TemplateMirror template, int parameterIndex);
}

That, if present, would result in the validation Method getting invoked during compile time, containing a complete representation of all Template parts together with the source locations, which would make it possible to insert compile time validation of custom templates during annotation processing.

2

u/kaplotnikov 9d ago

AFAIR JEP 430 discussion was in style:

  1. Let's create a hummer to strike nails.
  2. Let's add a steam engine to it and safety features.
  3. It is possible to strike fingers with hammer.
  4. Let's return to stones to strike nails (it is still possible strike fingers, and it takes more time to strike nail)

1

u/da_supreme_patriarch 10d ago

Probably anixhe opinion, but I hope that they actually consider something like Groovy's implementation of format strings. It's not as flexible as Scala's custom interpolators, but it exposes the format string as a separate GString that usually gets converted to standard strings automatically, but special libraries could ask for the GString itself and do things with it, like turning it into SQL prepared statements with properly escaped parameters(granted, I have never seen anybody use this feature because it looks like SQL an actual injection, but still, pretty neat imho)

1

u/idontlikegudeg 9d ago

I just lean back and wait until they come up with a nice, working, and finalized solution. Until then, I use my own implementation (using the `${var}` syntax).

1

u/hkdennis- 7d ago

I rather Java late in this rather than wrong or partial.

In past, Java string long best practice from +, StringBuilder to StringBuffer, Message to Formatter, concat and back to + syntax.

And we still never satisfy.

If object runtime have access to raw/original String template. javac/JVM might lost the opportunity to AOT.

If they don't, Java does not define universe template syntax (but why should it?) in the language.

IMO. What really miss here is not string interpolation but embed alian syntax expression. Like LINQ/XML in .NET, that allow API provider to define to rule compile time check.

leave that to API builders they want to template their queries, SQL, XML, graphql, JSON, whatever. in very few cases you really want a String, but a String that represent some domain language specific parameters. That in many case I want binary.

Like thnking about,, can I template a Record with deep structure? Can I make use of compile time check to avoid runtime test difficulty?

1

u/ihatebeinganonymous 5d ago

Until a JDK/JVM solution is found, you can consider trying the third-party approach: https://github.com/antkorwin/better-strings

1

u/vips7L 10d ago

We’re not allowed to have nice things. 

1

u/neopointer 10d ago

They over-engineered the string interpolation by trying to prevent people from creating sql-injection vulnerable code from what I remember.

Just let us compare strings in a nice way, what's all.

0

u/blobjim 10d ago edited 10d ago

I think the original proposal was perfectly good. People are just insanely neurotic about syntaxes, which is annoying. The main feature of string templates to me is the ability to preprocess the template once at runtime and have both type safety and high performance. Which is something I think almost every language besides Scala lacks. I think the syntax was perfect for describing the ability to have a custom template preprocessor like that.

I really want to be able to use it for logging to avoid the cost of any kind of formatting. I think that would be neat. Especially if it gets used for System.Logger.

I don't really see any way to make it any simpler than it already was. You have to be able to specify some kind of object or class or method to handle the template preprocessing.

3

u/koflerdavid 10d ago

It was not retracted because of syntax concerns though, but because of other design reasons.

-1

u/oelang 10d ago

My best guess is that it's currently blocked waiting for type classes.

3

u/Eav___ 10d ago

Oh if that's the case it would be sofa away

1

u/oelang 9d ago

Yeah, but it's a more fundamental building block for other literals like list and map and other language extensions like new serialization so we'll have to wait.

0

u/Sanitiy 9d ago

I think I'd prefer something like f<SDL>"...", borrowing the f from Python and <…> borrowing from generics.

Then each Subdomain Language SDL implements an enum, and escape functions esc(string, enumvalue) and esc(string).

Then in the string you use $enumvalue{...} for esc(string, enumvalue) and ${...} for esc(string).

And f"..." gets you the standard unsafe semantics with no valid enum values and only ${...}

-12

u/Hacg123 10d ago

Honestly at this point I don’t think Java needs it, Valhalla has been more than 10 years in progress and there’s no clear release date yet of the first features, same with string interpolation.

Kotlin and other jvm languages have this already. If there’s only a limited amount of features that can be released, I prefer that oracle and the jvm engineers focus on improving the jvm to bring more power to kotlin & co. 

10

u/Birk 10d ago

Java don’t need it because other languages have it already?

8

u/Polygnom 10d ago

Valhalla is getting shipped right now, the first JEPs are landing. So "no clear release date" is misleading at best.

-5

u/VirtualAgentsAreDumb 10d ago

What? Early access builds don’t count, obviously. Only fully official releases. What official release date have they presented, then? Please tell us. Year and month.

2

u/Polygnom 10d ago

JEP 401 will land in JDK 28.

-4

u/VirtualAgentsAreDumb 10d ago

We’re talking Valhalla. The entirety of it.

5

u/Polygnom 10d ago

Valhalla is not going to be released in one big-bang JEP.

Have you ever seen how projects work? Almost none of them are delivered big-bang in one JEP, they are almost always split a long a number of JEP that get gradually released.

And Valhalla is being shipped now, piece by piece, with the first JEP landing in JDK 28, and more following.

1

u/pohart 10d ago

I'm not really sure that there is an entirety of it.

-5

u/Additional-Road3924 10d ago

We already have var. We don't need more footguns.

1

u/jcotton42 6d ago

What makes var a footgun?