Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Shame they don't actually include templating inside of the string literal. Still have to append with a lot of tokenized replaces. Since they've committed to no formatting in the literal section, will be interesting to see if they eventually support a syntax like python's f-strings: f"""${foo}"""


Maybe you're looking for String::formatted?

Directly from http://openjdk.java.net/jeps/378:

  Another alternative involves the introduction of a new instance method, String::formatted, which could be used as follows:

  String source = """
                  public void print(%s object) {
                      System.out.println(Objects.toString(object));
                  }
                  """.formatted(type);


I'd still prefer honest-to-goodness string interpolation. Formatting functions with positional placeholders need a linter to be kept (vaguely) maintainable, and I suspect that formatting functions with named placeholders would be difficult to make acceptably ergonomic or performant in Java.


> I suspect that formatting functions with named placeholders would be difficult to make acceptably ergonomic or performant in Java

yamlp performs string interpolation from YAML files:

https://bitbucket.org/djarvis/yamlp/

I reuse my library in my text editor:

https://github.com/DaveJarvis/scrivenvar/

The text editor can interpolate strings in a variety of contexts (such as Markdown, R Markdown, XML, and R XML documents):

https://www.youtube.com/watch?v=u_dFd6UhdV8

As far as I can tell, there is no performance degradation from the recursive interpolation; the editor reads, interpolates key/value pairs, and substitutes the resulting values into R Markdown documents riddled with up to a thousand simple formulas in about 600 milliseconds (on my desktop computer).

Also, the editor provides a way to maintain the interpolated variables in a tree-like view:

https://github.com/DaveJarvis/scrivenvar/blob/master/README....

The substituted values appear in the preview pane in their final form. This is all real-time and pure Java.


Which one is easier to mess up and harder to debug afterwards?

A. "${label1} ${label2} ${label3} .... ${label 400}"

B. "%s %s %s ... %s".formatted(label1, label2, label23, ... label400) // Ooops, typo!


For the particular typo you gave, it seems to me to be equally likely with either method.


I'll admit it wasn't the best example.

Here, have another one:

I want to have a string with this content:

"Fluffy Nero Polly<random text> ... <random text> Trexxie"

Which one is easier to figure out and debug?

A. "${cat} ${dog} ${bird} <random text> ... <random text> ${dinosaur}"

B "%s %s %s <random text> ... <random text> %s".formatted(dog, giraffe, dinosaur, ..., cat).


Maybe A, but not (IMO) dramatically so. But shouldn't A actually be "${cat} ${dog} ${giraffe} <random text> ... <random text> ${dinosaur}"? That makes it closer in difficulty to B.

To me, the difference shows up more with this scenario:

A: "${v1} ${v2} ${v3} ${v4}"

B1: "%s %s %s %s".formatted(v1, v2, v3)

B2: "%s %s %s %s".formatted(v1, v2, v3, v4, v5)

B3: "%s %s %s".formatted(v1, v2, v3, v4)

A does what you tell it, whether it's wrong or right. B has a chance of warning you that the argument list and the format specifier don't match. On the other hand, B gives you two things that have to be kept in sync with each other, and A can't get out of sync, since there's only one thing.

So: Less of a chance to make the error, or more of a chance to catch it. Which is better? I lean toward A, but I will admit that it seems subjective.


> Less of a chance to make the error, or more of a chance to catch it.

B only catches mistakes in the case that the number of parameters doesn't match the number of placeholders, which isn't even possible with A. If the string you built isn't correct, that's on you in either case, and should be immediately obvious by looking at the output. So in that sense, interpolation is strictly better than `formatted` at dealing with potential mistakes.


Go doesn't have interpolated strings but printf / sprintf and co, and its compiler will warn and error if your arguments do not line up or have the wrong type.

I mean it's not ideal, but sprintf and co are only intended for relatively short text (like logging), if you have any more, use a templating language instead. Plenty of those in Java as well (JSP, Velocity, etc).


This was already there, and is much less user-friendly than string interpolation, because it's easy to mess up order


http://manifold.systems/ has a Java template engine that can be helpful


Will definitely check it out!


The Manifold project[1] provides string interpolation for Java. You enable it as a Java compiler plugin, it's pretty cool.

[1] https://github.com/manifold-systems/manifold/tree/master/man...


while cool, it's pretty telling that similarly high-level languages like C#, Kotlin, Scala, Python, Swift and Javascript have had this widely-used quality of life for years while Java doesn't


And by telling I think you mean that over time Java has very thoughtfully evolved in a way that respects backwards compatibility, or that once a feature is in the language it'll very likely stay there for the next 25 years. Yes, innovation is very important (and happening faster than ever now with the 6-month release cadence), but a majority of the work isn't in deciding what goes in, it's deciding what stays out and if something does go in how does it satisfy both audiences of "move slow don't break" and "move faster we want features".

A good video on this process: https://www.youtube.com/watch?v=2y5Pv4yN0b0


Thanks. Looks very interesting


I'm glad Java is being conservative and not doing that. JS/Python f-strings have not proven themselves long-term. It also bloats the language with yet another mini-DSL. You can always add a proper templating engine on top.


Java relies on String + Object for composing strings, thus unsafely converting any object into string. An implicit conversion, akin to what JavaScript is doing.

String interpolation would be safer, as it would make the intent clearer, and you wouldn't risk bumping in corner cases. It would be even safer if the protocol could be overrided such that you wouldn't have to use Object#toString, but for Java that's too much already.

Java has been a very conservative language. And I understand why.

But it's funny how, for many features that were added later, people were rationalizing their absence with such lines too. E.g. we don't need anonymous functions / lambdas, as anonymous classes are enough. Well, turned out that Microsoft was right all along when they released those in J#.

Also adding a template engine is overkill for doing string concatenation.


> But it's funny how, for many features that were added later, people were rationalizing their absence with such lines too

There's nothing wrong with that. If string interpolation is really useful, then Java will add it some years down the line.

It's cheap to add features but literally impossible to remove them. There's no way to undo a mistake in language design. That's an asymmetry. I'd rather err on the side of caution than kitchen-sinking it.


Oh, I don't know about that. I wouldn't call it impossible.

I like how Java binaries still work on the latest Java, however, if distribution happens via binaries, why should the language keep source compatibility anyway?

Or, you know, the latest compiler could allow you to select the source code version you want. And automated code migration tools can work too.

---

Err'ing on the side of not getting features is why Java has lost a lot of mindshare.

Java is still super popular, but that's basically in spite of the language itself, because the language is awful.


> If string interpolation is really useful, then Java will add it some years down the line.

Now is the year. String interpolation is really harmless feature.


It deeply pains me that String is only a concrete type and that Object.toString() does not implement an interface.


J++, J# was as transition into .NET.


Indeed, you're correct.


> JS/Python f-strings have not proven themselves long-term.

Are you saying that they haven't been around for long or that they failed? If latter, then I respectfully disagree. Any recent JS and Python code I have seen uses them extensively. They are also a joy to use, and imho improve readability immensely. Ergonomics matter. This is one aspect of Python3 I would miss the most if I had to go back to 2.


Conservative? We've had "f-strings" since 1979, at least.


The ones in Python work significantly differently though; they have inline code execution (rather than using a varargs list after the f-string itself).


So does shell script and several modern programming langs. The sky hasn't yet fallen.


The Bourne shell had parameter expansion in strings in 1979, just FYI.


I've just executed:

echo "$(ls)"

in my zsh, so I'm not sure what to say, to be honest.


Closer to:

echo "Username is ${USER}"

As I recall (and Wikipedia seems to confirm), parameter substitutions were in the original bourne shell in 1979, so... Yeah, I'm not sure what's going on there.




Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: