"String s = String.interpolate(`text \{variable}`)" is not enterprisey enough. We need a few more levels of abstraction, like a StringFactory and a StringFactoryLocator.
Look out for the DevelopersResponsibility class, it has a lot of functionality concerning our own responsibility as developers to stand our ground on what we consider to be good practices for our work, despite the gibberish and bureaucratic old ways of doing things in big companies.
Yeeah. I personally liked "STR." when it comes to actually typing/reading it but maybe there is some other solution. Maybe there is something worth in consistency with number type notation? (so 10L)
I am glad to see Java feature experimentation in the open for developers to see. It is also good to see that the JEP process allows for change, while the enhancement is still being developed.
Yep, exactly. I'm disappointed to see templates disappear, but this process has brought us a lot of goodies over the last few years, so they've earned the benefit of the doubt. :)
if another reason for string templates was because String::format was so inefficient, but the reason they thought they needed string templates to be that way was for the efficiency, but that was later shown to be wrong... has anyone thought about just making String::format more efficient using that learned lesson while we're about it? 🙂
I looked into this. It turns out, the FMT implementation borrowed much of its code from the explorations for JEP 348 (openjdk.org/jeps/348), which explicitly mentions `String::format`. So there is a JEP tracking this. I don't know what that means for the near future, though. Will JEP 348 move forward to prove that processors really aren't necessary before string templates progress? Or is this already established to the point where both JEPs can move on independently? Will `String::format` have to wait for its optimization through JEP 348 or can/will it be special-cased before that? Your guesses are as good as mine...
As a general rule, you should assume the answer to any question of the form "has anyone thought of..." is "yes". In fact, the StringTemplate feature _grew out of_ experiments to optimize String::format.
Really good video spiced with some humor. Very good summarization about the preview feature idea and very detailed information about the why etc. about String Templates. Great.
I, for one, liked the old proposal as it was. Backslash-curly was an elegant solution (preference for $ seems irrational to me) and the STR."" syntax was concise and clear. But this JEP process has brought a lot of amazing improvements to Java so I trust the process and I'm excited to see where it lands.
@@samfromuk796 See 7:35. First: That a feature and particularly a specific syntax works well in one language doesn't mean that it works well in another one. Second: More than that, it may not even be optimal in that language - designers do make mistakes, after all. 😉
I'm hearing a lot of "forget about it". The Java community will not be happy. I personally enjoy JS String interpolation with backticks, it feels so easy. Such a pitty. I hope it works out in the end.
Aside Javascript, most DSLs today use ${}. So it is a familiar notation in devops today and introducing another notation for string template is just bad.
I don't use String Templates that much, but why don't copy the C# string interpolation, $"{my_var}" it looks kinda elegant ($ it's more elegant than \ ), so when applying the $ symbol before the quotes, it scapes the bracket caracter { , that'd be my solution.
The mailing list discussion indeed considers marking string templates with a sigil like `$`, e.g. `StringTemplate t = $"text \{variable}"`. But if any `{...}` section would then be interpreted as an expression, you'd still have to escape any curly brace you want to show up as is. And when you turn a `StringTemplate` back into a `String` while refactoring, you have to undo all those escape. This conceptual load seems unnecessary - just use `\{...}` for expressions and there's never any unnecessary (un)escaping.
What's more, Roslyn can lower interpolated string expressions to special calls to a "handler" builder type, which lets you write `dbSet.FromSql($"SELECT * FROM users WHERE id = {id}")` without ever risking SQL injection - the handler handles this behind the scenes to parametrize the query and escape the parameter.
@@nipafx It's target typing, the same thing it does in LINQ with expression trees. If the target of a string template is of type FormattedString, it's passed in uninterpolated. I think the original goal was to avoid making temporary strings when logging or printing, but it can have other uses as well. FormattedString is almost like StringTemplate in Java, except it does not have a list of text chunks, it has a string that matches what you would pass to String.Format, so your processor has to parse it itself.
@@vytah So, in Java terms, I could call a method that takes a java,sql.Statement but pass a StringTemplate and then the runtime goes looking for a StringTemplate~>Statement converter?
If at the end String Templates couldn't be added at all, I think at least the interpolation can stay. Since, as mentioned, the \ is a escape char, it woudn't break anything if you just add interpolations to normal strings like String str = "\{myVar}";
I think that's a terrible idea. It makes an easy-but-dangerous practice (carelessly embedding variables in strings) even easier without adressing the danger (injection attacks) at all. See 5:20 for a longer explanation.
I don't understand what's the issue of just copying it from JS. `Look, ${name}, doesn't this look just better`? And if you ever need to sanitize the input as with SQL queries you can just make the `` strings be a different class that inherits from String and has some additional functionality attached to it where you can access the interpolated strings, it would be both OOP-like and clean for developers.
I don't really get the security point. Why it should be goal of string templates? If injection is a concern, the sanitization should be left to the function/processor of whoever consumes the string template. My experience is mainly with JS version of string templating, and I don't feel insecure at all since many SQL libraries solve it just like I described - by processing/sanitizing the string template values with their own functions that take string template as parameter.
String templates aren't needed to make security possible as there are already perfectly safe ways to create, e.g., SQL statements based on user input. Alas, they aren't always used (or injection attackes wouldn't be in the OWASP Top Ten). And a big reason why they aren't always used is because string concatenation is so much easier. So if you can find a way to make templating/interpolation just a bit easier than concatenation but as safe as the proper approaches, that would be a huge win. And that's a goal worth working towards; much more than just removing the inconveience of ` + `. JS's template strings aren't a good example and shouldn't be adopted by Java. It makes the wrong choice (injecting unchecked variable values into strings) the easiest one and leaves you to go the extra mile (wondering which tag function to tack on). But at least the tag function has access to the string portions and the variables, so that's good. I agree when you say "sanitization should be left to the function/processor". But for that to happen reliably, it must be a goal of the design process. And that's why security is a goal for string templates.
Short version, StringTemplates make it possible for a library to force the safe AND convenient way, instead of choosing to support one or both. They don't wanna break things all over the place but if they had string templates from the start, jdbc would have been implemented to take a StringTemplate as query and values, and do the mapping into a PreparedStatement internally, never exposing a string interface that lets users create unsafe queries.
@@nipafx driving without seat belt is much more comfortable, but we all know the consequences, trying to dictate what people should do in language is just not right, listen to the community, we just want interpolation, we don't want crazy syntax, we don't want "security".
@@shadeblackwolf1508 You could always concatenate strings and then use it as an parameter for the StringTemplate. I think the string template must take an String? If that isn't possible I would be in trouble because then it would be impossible to make the queries more dynamic than just use variables.
The reason why ${} is familiar has little to with other languages. It's familiar because it's used in things like Spring's "Spring Expression Language" .
And that is exactly why it cannot be used. Java does not want to break all your existing code using existing library placeholders. If they used ${, then spring would never be able to see that character combination. And every codebase running on old versions of spring where that processor expects a String, not a StringTemplate, would break.
Are you sure more Java devs use SpEL et al. than, say, JS, Kotlin, Scala, and bash put together? Either way, the reason people cite when arguing for $ is more often one of these languages than SpEL. And that's not a bad idea because Java-string-based languages using $ is a really good reason for Java's string templates _not_ to use them, so bringing up SpEL et. al as an argument _for_ $ is an own goal.
@@nipafx It's not just SPeL though. Thymeleaf uses it. Apache Velocity and Freemarker use it. I really think the familiarity comes from within the Java community itself, not from what other languages are doing.
@@shadeblackwolf1508 I'm not arguing that String Template should or shouldn't use ${}, I'm arguing that the familiarity for it from Java developers comes from it currently being used by them with Java already, not that it's coming from other languages which the video implies.
@@shadeblackwolf1508 Also, if String Templates could break existing code, then they shouldn't be added full stop. (And the more I think about it, the more I question the need for String Templates to be baked into the JDK, when we already have several template libraries other than "other languages do it and it would be kind of cool")
I'm sure I'm not alone in that this was the first Preview feature I actually bothered using in real-world code. Specifically, it makes writing tests so much more elegant, for example, formatting JSON. To have it be removed with no migration path to a non-preview alternative is unfortunate. I suppose I can just stay on Java 21 as it is widely LTS supported and migrate once an alternative is available.
why not allow syntactic sugar like "kotlin" approach but as part of the java lang? (u mentioned security but c#/kotlin/scala/every other lang in the world allow it)
Could you implement it such that String Template literals look just the same as regular Strings (i.e. just regular double quoted or text block) and keep the type of the literal indeterminate until it is either assigned to a variable, gets typecast, or a method is invoked on it (e.g. `"myString".length()`)? Here's what I mean: - When the literal is assigned or cast to anything other than StringTemplate, treat it as a String, otherwise as StringTemplate - When a method is invoked on literals directly or `+` concatenation is used, always treat them as a String - When assigned to `var`, treat it as either a String or StringTemplate depending on whether it contains String Template sequences - When treating the literal as a String, produce a compiler error in case it contains any String Template sequences This would be somewhat similar to how lambda expressions are already being handled by the compiler.
It was discussed somewhere in that mailing list thread by Maurizio Cimadamore, the result was that it doesn't work that well: there are problems with overloads (choosing between m(String) and m(StringTemplate) for m("X")) and with generics (List l = List.of("X"); fails to typecheck, and fixing that would require overhauling the entire typechecker)
@@vytah My suggestion would be that these cases are treated as String unless cast explicitly to StringTemplate (e.g. m((StringTemplate)"X") or a type witness is used (e.g. List.of("X")). Considering these are probably fairly niche usages I would argue that the cumbersome syntax is justifiable. But maybe there are problems with that which aren't obvious from a non-language engineer perspective.
The mailing list conversation @vtah mentioned started with this mail: mail.openjdk.org/pipermail/amber-spec-experts/2024-March/004016.html I recommend to give it a read. If you think you found a solution that doesn't have these issues (which is entirely possible!), I recommend to send it to the mailing list. It can really make a difference there! (Unlike here on TH-cam. 😉)
With the raise of AI and the need for strong textual support, this is a real let down. From my own experience, my team and I were heavily testing with new ideas with processors and API design and personal I think this sets back Java a couple years in making it a "better choice" for new developers. The world of development is moving away from hassling with code to more of a friendly (get the job done) experience, Java keeps showing it's disdain for fun.
That was a special video just like your explanation ♥ We trust Java architects are going to propose something great like they always did for past three decades
@@mralix9566 in kotlin they made them right, you declare variance of a generic parameter once. if the class is both covariant and contravariant on the same parameter, you have to introduce two interfaces. this makes generics much less verbose and easier to use. in java you have to declare variance on every method. as a result, in kotlin skilled dev can design generic api once and then less skilled devs would just use it barely noticing. in java everyone has to deal with them leading to more confusion and bugs. some teams even chose not to bother with generics at all, and you'll have less expressive apis in the end I guess they didn't want to redesign again their new and shiny collections, which they designed mutable by default. mutable collections are an example of both co- and contravariant type and had to be redesigned if they went the kotlin way from the start also there is type erasure. usable metainfo just absent from the class files and one cannot get it back via reflections. thus poorer metaprogramming also primitive generic params have to be boxed, and it's slower
Why not treat templates similarly to regex patterns? Something like Template t = String.compile(`Hello, @{name}!`) Then you can run t.process("world") to get the result.
If syntax is going to be a regular method call, I'm definitely in. This is highly subjective but somehow `STR."..."` syntax is hard to read, it just puts too much focus on the STR rather than string content itself. I think the syntax does matter. Idea of `String.interpolate("Whatever \{foo}") is not too bad. Let's see what it is going to eventually become. BTW: Only JS uses dollar sign? Perl, PHP, Bash, Groovy, Scala, Kotlin,.. (yeah...)
StringInterpolatorFactory(new StringTemplate(new Thread()).interpolate(new StringExpression("/{value}"), new StringTemplateParams()).build().toString(). That's how to make it entetprisely.
I really wished they wouldn't have use \ for escaping. It's just so cumbersome to type on a german keyboard. i get the backwords compatibility aspect of it. I just hpped they would have considered the internationalizational aspect of that feature.
Specifically on a German keyboard, this argument seems so strange to me! 0, =, ß, ?, ` are all frequently used characters and they're all right there on the same or neighboring keys. Are you really saying that you embed so many variables in strings that it will significantly increase your use of those keys, overshadowing `=`? Also, \{ is only one modifier whereas ${ are two, which makes it feel much more cumbersome to me.
@@nipafx The number of variables embeded in string qould increase significantly if String templates would have made it as a full feature. But that is not my point. If you look at the american keyboard layout, frequently used characters in programming like \, [, ], /, ` etc are primary characters, meaning you do not need to hold another key to type them. On the german keyboard, these are either secondary or tertiary characters, so you need two or more key additionaly to type them, which in my optinion makes them automatically more cumbersome to type. I am sure there are other keyboard layouts with similar issues with different characters, and you can not accomondate all of them, but by using the backslash it seems like the designers were only looking at the american keyboard layout and did not consider the typing experience on other layouts.
No need for a video: "It's complicated work and not the only / most important thing that's happening right now. It's ready when it's ready - hopefully soon." There you go, video avoided. PS: Trust me, there are very few people in our community that want it to happen NOW more than me. 😖 th-cam.com/video/kzjGp7LmW0I/w-d-xo.html
@@percival477 A Valhalla history lesson? Not a bad idea, but challenging. If you want to look into it yourself, search for "Brian Goetz Valhalla" and pick some of the presentations, e.g. th-cam.com/video/1H4vmT-Va4o/w-d-xo.html
JavaScript may be the only CURRENT top ten Tiobe language to use ${}, but there are plenty of us who write bash scripts, some who use Groovy directly or indirectly (e.g. Gradle), and some poor, unfortunate folks who use PHP. For better or worse, PHP was a top 10 language.
Why we can not use %s{} as a combination of existing string format syntax and new possibility? We can even have %{} for cases when we do not want force processor to interpolate value as string and give it ability to decide which representstion is better.
Every syntax that can appear today in a valid Java string literal suffers the same backward-compatibility problem. \{} is better because no existing string literal can contain it.
Enjoyed the video and learned a lot about the state of string interpolation. However, the arguments presented against the dollar sign as a special character in string interpolation are extremely weak. First, devs would use string interpolation 100x or 1000x times more often than a currency indicator or whatever other purpose it is used for. Second, while someone's top 10 languages list may only include one that only uses dollar sign interpolation, that one is used in 99% of all web applications. That's like saying that of the top 10 substances found in the ocean, only one is water. Not to mention that there are two close cousins to the top 10, namely Typescript and Groovy, that use dollar sign and curly braces for string interpolation.
The point about water is pretty good - made me chuckle. 👍But what about 99% of all system code being written in a language that doesn't have any interpolation? There is zero water in... (well, that's actually unfair because water is everywhere) ... the sun, there's zero water on the sun. So I can apply your logic and then we don't need string interpolation? 😉 What I'm trying to say is that across all languages, interpolation by dollar sign is far from ubiquitous. We don't agree on how strong the arguments against $ are but we seem to agree on there being some. Given that I've heard none in favor, \{ still seems to come out ahead.
Yeah, in fact they already did have that in JDKs 21 and 22. I didn't use it at 10:33 because it favors one out of all possible "StringTempalte -> ..." transformations. E.g. `Statement.create("text \{variable}")` would then be harder to discover and longer than `"text \{variable}".interpolate()`, which I don't find ideal.
Syntactically it's incovenient that the placeholder and the variable are so far apart, performance-wise it's just slow compared to concatenation, and from a security point of view it lacks the capability to apply format-specific rules (e.g. SQL, JSON, etc.) before user content is interpolated into the string. Not all of those issues matter in all situations and `String::format` is definitely ok to use (I do it a lot and generally prefer it over string concatenation), but there's room for improvement.
It is damn expensive. I wrote an alternative implementation using an iterative approach, instead of transforming the format string to an object presentation at first. That performs ways faster, but with the downside, that it may output some part of the result at first, before failing due a syntax error. Furthermore, in my humble opinion, String.format() is overbloated with much too many features. In 99.9% of all cases people are just using "%s".
I don't understand why you can't just start with both the triple-quote """ and the \{var}, and then leave the rest of the crap out! Those two compiler-syntactic structures seem to capture the essence of what Java is trying to accomplish here. I mean, I will admit I haven't even used these templates yet, but the value of it all looks (to me) like it can be summarized in those two features. After that - adding "RAW", "STR", "FMT", and "ARBITRARY" is where the actual "featur-itis" starts to occur. - Please disagree with me. Sincerely, Ralph
@@nipafx Well ... Clearly the answer isn't `java.lang.String`, or you wouldn't have posted this as a reply. Ummm... So... May I ask what on earth is preventing the answer from being `java.lang.String`?
@@rtorello75 Hey, you're designing this language feature, it can be whatever you want. 😉 `String` would absolutely work. What would the effects be? Every Java developer would be a bit happier when mixing strings and variables - that's nice. But we would've done nothing to reduce the prevalence of a security problem (specifically, injection attacks) that is a serious problem in our industry and causes some of the applications these developers write to lose all their user data. Oops. What if we instead find a way to make this new feature more elegant than concatenation (so developers will actually use it) but as safe as The Proper Way to combine strings and variables? (What exactly that is depends on the domain, but for, e.g., SQL it would be prepared statements.)
You're nicer than the person I portray at 5:20 but everything I say in that section applies to your request. TL;DW: The mild inconvenience of typing ` + ` is orders of magnitude less important to fix than the security issues caused by injections.
If only there was any language in the JVM world that did have an interpolation working elegant and secure for years. That would’ve made all of these arguments against templates and interpolation quite awkward. Luckily, we live in 2001 and Scala hasn’t been invented yet.
I don't recall a single argument against templates and it seems Scala had the same thoughts on interpolation or they wouldn't have picked the approach they did. So on those two topics Scala and Java agree. And even Scala's solution and Java's retracted proposal are very similar. I think the main difference is that Java balked at the weird syntax, something that never bothered Scala.
@@nipafx would do you mean by “weird syntax”? Here’s an example of valid Scala code s”Hello, World! 1 + 1 = ${1 + 1}” sql”insert into users (name, age) values (${user.name}, ${user.age})” The second one needs a library though, but it’ll create SQL statements and handle escaping for you. If that looks weird, I’d be happy to see not-so-weird Java version of examples above
@@nikitamyazin6586 Have you ever called a method in Java with `method args` without parenthesis? The non-weird way would be `sql("...")`. A lot of people, Java users as well people working on the language, were uneasy about introducing an additional, one-off method invocation syntax. (Personally, I didn't mind that much.)
@@nipafx for me that sounds like an issue with people that don’t want to learn anything new. Programming languages should evolve over time, you can’t make them meet modern expectations based purely on ideas that existed 30 years ago. So while it’s valid a concern, it shouldn’t be a show stopper.
@@nikitamyazin6586 It's not a show stopper - it was proposed like that after all. But it's a downside of the proposal. And I think it's you who doesn't want to learn anything new (if you balk at that statement, you were just as unkind to other people), in this case the considerations behind designing a language and the benefits of conceptual simplicity.
the character to use in template does not really matter. The bad part is the STR."" The only good way is to be able to do "my \{variable}" and to be able to pass it every where I can pass a String. We don't want to call toString() every time we want to use it, this should be a "String" by default nothing else.
Or Kotlin and Groovy language designers made mistakes (just like Java designers did, btw) and we can do better. 😉 I think that possibility is at least worth exploring.
So it won't be re-introduced as a Java 24 JEP? Really? You are kidding, right? A lot of us who want string templates will be stuck on Java 22. for a while ... Thank you Oracle, you could not just ship the feature "as is" in Java 23 without officially listing in the JEPs list?
If you're stuck on any version, please don't make it 22! I'm not aware of any vendor providing updates for that after September. If you absolutely have to, you can use the feature just the same on JDK 21. More importantly, though: If you committed to a preview feature so hard that you're now stuck on a JDK release, you're doing it wrong. You must've ignored _all_ the warning signs - the barrier tape, the blinking red light, the sirens, the people in yellow vests hectically yelling and waving at you from afar... They were all trying to tell you to never write more code against a preview feature than you're willing to throw away and rewrite.
Strong disagree. I was looking forward to a nice way to not have to think about SQL injection risks every time i write an sql query with dynamically included parts.
@@shadeblackwolf1508 But the thing is that most SQL library APIs use positional/named parameters, so it's not really a security problem as you say. Saying string templates are there for security also is not good enough of an argument. String templates/interpolation should be there for convenience and not for security. Security aspect is already handled by widely used SQL libraries.
The java community process is one of its kind. Moving an important language is hard. The last 20+ years Oracle and the java community have done (remarkably) well in my opinion.
@@MeriaDuck what you said is correct. I started working with Java 6 and java 7 and thing went really well recently. But some features are really needed for the language such as ?. (that returns null instead of NPE) string templates as any other language. rethink getters/setter (so we don't have to use lombok). default parameters for methods and constructors. I know this is not easy because of backward compatibility but people are still using Java 7 and 8 anyways. I mean we should not be afraid to break things if we want java to live in this era.
@@ramdaneoualitsen1323 many of those features are available on the JVM in the form of kotlin. Java may or may not follow everything that is fun in Kotlin
@@bluemeriadoc But then users have to learn two completely different rulesets for what's essentially the same thing: a string of characters. And the sole benefit is a little less typing - and of curly braces of all things, which Java devs already have on speed dial. 😉
@@bluemeriadoc I'm not convinced of backticks either. I think "..." with some prefix would work best. I just used backticks in the video as the simplest-to-understand example syntax.
"Damn. " + "I was very excited about string templates. "
var pronoun = me;
println(pronoun + " too");
@@shadeblackwolf1508
var timeline = "soon";
str("Hopefully, we get them /{timeline}");
"String s = String.interpolate(`text \{variable}`)" is not enterprisey enough. We need a few more levels of abstraction, like a StringFactory and a StringFactoryLocator.
Good point, will forward to Project AmberFactoryLocator!
Look out for the DevelopersResponsibility class, it has a lot of functionality concerning our own responsibility as developers to stand our ground on what we consider to be good practices for our work, despite the gibberish and bureaucratic old ways of doing things in big companies.
StringTemplateFactoryLocatorDelegateSupplier
I'm just gonna say it, if it's long and unwieldy to use (aka worse than str.) then people will tend not to use it, regardless if it's secure or not
*sneeze* module *sneeze*
I agree and that's the challenge here: Finding a way to structure the feature, so it ends up being safer _and_ more usable than concatenation.
Yeeah. I personally liked "STR." when it comes to actually typing/reading it but maybe there is some other solution. Maybe there is something worth in consistency with number type notation? (so 10L)
He covers that point in the video.
Just take ideas from the almighty C#, it's so elegant.
I am glad to see Java feature experimentation in the open for developers to see.
It is also good to see that the JEP process allows for change, while the enhancement is still being developed.
Yep, exactly. I'm disappointed to see templates disappear, but this process has brought us a lot of goodies over the last few years, so they've earned the benefit of the doubt. :)
Thank you for the care of making it thought-through, well and consistent with all of Java!
if another reason for string templates was because String::format was so inefficient, but the reason they thought they needed string templates to be that way was for the efficiency, but that was later shown to be wrong... has anyone thought about just making String::format more efficient using that learned lesson while we're about it? 🙂
I wondered about that, too. Will try to find out.
+1 to this. This way string template can take all the time it needs but the community using latest java will benefit on optimization of String::format
I looked into this. It turns out, the FMT implementation borrowed much of its code from the explorations for JEP 348 (openjdk.org/jeps/348), which explicitly mentions `String::format`. So there is a JEP tracking this.
I don't know what that means for the near future, though. Will JEP 348 move forward to prove that processors really aren't necessary before string templates progress? Or is this already established to the point where both JEPs can move on independently? Will `String::format` have to wait for its optimization through JEP 348 or can/will it be special-cased before that? Your guesses are as good as mine...
As a general rule, you should assume the answer to any question of the form "has anyone thought of..." is "yes". In fact, the StringTemplate feature _grew out of_ experiments to optimize String::format.
Really good video spiced with some humor. Very good summarization about the preview feature idea and very detailed information about the why etc. about String Templates. Great.
I, for one, liked the old proposal as it was. Backslash-curly was an elegant solution (preference for $ seems irrational to me) and the STR."" syntax was concise and clear. But this JEP process has brought a lot of amazing improvements to Java so I trust the process and I'm excited to see where it lands.
I agree with your entire statement. 💯
Why is ${} irrational? It's used in Bash scripts a lot and it's in Groovy.
@@samfromuk796 See 7:35. First: That a feature and particularly a specific syntax works well in one language doesn't mean that it works well in another one. Second: More than that, it may not even be optimal in that language - designers do make mistakes, after all. 😉
@@samfromuk796Backwards compatibility
@@samfromuk796 ${} has backward compatibility problems that \{} does not. It is objectively worse for this application.
I'm hearing a lot of "forget about it". The Java community will not be happy. I personally enjoy JS String interpolation with backticks, it feels so easy. Such a pitty. I hope it works out in the end.
Aside Javascript, most DSLs today use ${}. So it is a familiar notation in devops today and introducing another notation for string template is just bad.
Agreed, but at times we also need to re-think those decision and not stick to conventions that prove to be bad.
I don't use String Templates that much, but why don't copy the C# string interpolation, $"{my_var}" it looks kinda elegant ($ it's more elegant than \ ), so when applying the $ symbol before the quotes, it scapes the bracket caracter { , that'd be my solution.
The mailing list discussion indeed considers marking string templates with a sigil like `$`, e.g. `StringTemplate t = $"text \{variable}"`. But if any `{...}` section would then be interpreted as an expression, you'd still have to escape any curly brace you want to show up as is. And when you turn a `StringTemplate` back into a `String` while refactoring, you have to undo all those escape. This conceptual load seems unnecessary - just use `\{...}` for expressions and there's never any unnecessary (un)escaping.
What's more, Roslyn can lower interpolated string expressions to special calls to a "handler" builder type, which lets you write `dbSet.FromSql($"SELECT * FROM users WHERE id = {id}")` without ever risking SQL injection - the handler handles this behind the scenes to parametrize the query and escape the parameter.
@@neonmidnight6264 In the example you gave, how's the '"handler" builder type' selected?
@@nipafx It's target typing, the same thing it does in LINQ with expression trees. If the target of a string template is of type FormattedString, it's passed in uninterpolated. I think the original goal was to avoid making temporary strings when logging or printing, but it can have other uses as well. FormattedString is almost like StringTemplate in Java, except it does not have a list of text chunks, it has a string that matches what you would pass to String.Format, so your processor has to parse it itself.
@@vytah So, in Java terms, I could call a method that takes a java,sql.Statement but pass a StringTemplate and then the runtime goes looking for a StringTemplate~>Statement converter?
I will die faster than Java will be like a convinient language
If at the end String Templates couldn't be added at all, I think at least the interpolation can stay. Since, as mentioned, the \ is a escape char, it woudn't break anything if you just add interpolations to normal strings like String str = "\{myVar}";
I think that's a terrible idea. It makes an easy-but-dangerous practice (carelessly embedding variables in strings) even easier without adressing the danger (injection attacks) at all. See 5:20 for a longer explanation.
It's more likely we get generic string templates without string interpolation than string interpolation without generic string templates.
I don't understand what's the issue of just copying it from JS. `Look, ${name}, doesn't this look just better`? And if you ever need to sanitize the input as with SQL queries you can just make the `` strings be a different class that inherits from String and has some additional functionality attached to it where you can access the interpolated strings, it would be both OOP-like and clean for developers.
String is final and for a million reasons (not least of which is performance), it absolutely needs to remain that.
That's why i love Java, the goal is not just for work
I don't really get the security point. Why it should be goal of string templates?
If injection is a concern, the sanitization should be left to the function/processor of whoever consumes the string template.
My experience is mainly with JS version of string templating, and I don't feel insecure at all since many SQL libraries solve it just like I described - by processing/sanitizing the string template values with their own functions that take string template as parameter.
String templates aren't needed to make security possible as there are already perfectly safe ways to create, e.g., SQL statements based on user input. Alas, they aren't always used (or injection attackes wouldn't be in the OWASP Top Ten). And a big reason why they aren't always used is because string concatenation is so much easier. So if you can find a way to make templating/interpolation just a bit easier than concatenation but as safe as the proper approaches, that would be a huge win. And that's a goal worth working towards; much more than just removing the inconveience of ` + `.
JS's template strings aren't a good example and shouldn't be adopted by Java. It makes the wrong choice (injecting unchecked variable values into strings) the easiest one and leaves you to go the extra mile (wondering which tag function to tack on). But at least the tag function has access to the string portions and the variables, so that's good.
I agree when you say "sanitization should be left to the function/processor". But for that to happen reliably, it must be a goal of the design process. And that's why security is a goal for string templates.
Short version, StringTemplates make it possible for a library to force the safe AND convenient way, instead of choosing to support one or both. They don't wanna break things all over the place but if they had string templates from the start, jdbc would have been implemented to take a StringTemplate as query and values, and do the mapping into a PreparedStatement internally, never exposing a string interface that lets users create unsafe queries.
@@nipafx driving without seat belt is much more comfortable, but we all know the consequences, trying to dictate what people should do in language is just not right, listen to the community, we just want interpolation, we don't want crazy syntax, we don't want "security".
@@mchiareli So you're proposing that most (all?) nations in the world should make coding without proper string templating a crime?
@@shadeblackwolf1508 You could always concatenate strings and then use it as an parameter for the StringTemplate. I think the string template must take an String? If that isn't possible I would be in trouble because then it would be impossible to make the queries more dynamic than just use variables.
The reason why ${} is familiar has little to with other languages. It's familiar because it's used in things like Spring's "Spring Expression Language" .
And that is exactly why it cannot be used. Java does not want to break all your existing code using existing library placeholders. If they used ${, then spring would never be able to see that character combination. And every codebase running on old versions of spring where that processor expects a String, not a StringTemplate, would break.
Are you sure more Java devs use SpEL et al. than, say, JS, Kotlin, Scala, and bash put together? Either way, the reason people cite when arguing for $ is more often one of these languages than SpEL. And that's not a bad idea because Java-string-based languages using $ is a really good reason for Java's string templates _not_ to use them, so bringing up SpEL et. al as an argument _for_ $ is an own goal.
@@nipafx It's not just SPeL though. Thymeleaf uses it. Apache Velocity and Freemarker use it.
I really think the familiarity comes from within the Java community itself, not from what other languages are doing.
@@shadeblackwolf1508 I'm not arguing that String Template should or shouldn't use ${}, I'm arguing that the familiarity for it from Java developers comes from it currently being used by them with Java already, not that it's coming from other languages which the video implies.
@@shadeblackwolf1508 Also, if String Templates could break existing code, then they shouldn't be added full stop.
(And the more I think about it, the more I question the need for String Templates to be baked into the JDK, when we already have several template libraries other than "other languages do it and it would be kind of cool")
I'm sure I'm not alone in that this was the first Preview feature I actually bothered using in real-world code. Specifically, it makes writing tests so much more elegant, for example, formatting JSON. To have it be removed with no migration path to a non-preview alternative is unfortunate. I suppose I can just stay on Java 21 as it is widely LTS supported and migrate once an alternative is available.
why not allow syntactic sugar like "kotlin" approach but as part of the java lang? (u mentioned security but c#/kotlin/scala/every other lang in the world allow it)
public static String f(StringTemplate t) {
return String.interpolate(t);
}
var muchBetter = f(`Hello \{world}`);
and add a replace all ${ to \{
I don't like the `\{` syntax because `\` escaping the next char, so the string `text \{var} test` looks to me unbalanced.
Could you implement it such that String Template literals look just the same as regular Strings (i.e. just regular double quoted or text block) and keep the type of the literal indeterminate until it is either assigned to a variable, gets typecast, or a method is invoked on it (e.g. `"myString".length()`)? Here's what I mean:
- When the literal is assigned or cast to anything other than StringTemplate, treat it as a String, otherwise as StringTemplate
- When a method is invoked on literals directly or `+` concatenation is used, always treat them as a String
- When assigned to `var`, treat it as either a String or StringTemplate depending on whether it contains String Template sequences
- When treating the literal as a String, produce a compiler error in case it contains any String Template sequences
This would be somewhat similar to how lambda expressions are already being handled by the compiler.
It was discussed somewhere in that mailing list thread by Maurizio Cimadamore, the result was that it doesn't work that well: there are problems with overloads (choosing between m(String) and m(StringTemplate) for m("X")) and with generics (List l = List.of("X"); fails to typecheck, and fixing that would require overhauling the entire typechecker)
@@vytah My suggestion would be that these cases are treated as String unless cast explicitly to StringTemplate (e.g. m((StringTemplate)"X") or a type witness is used (e.g. List.of("X")). Considering these are probably fairly niche usages I would argue that the cumbersome syntax is justifiable. But maybe there are problems with that which aren't obvious from a non-language engineer perspective.
The mailing list conversation @vtah mentioned started with this mail: mail.openjdk.org/pipermail/amber-spec-experts/2024-March/004016.html I recommend to give it a read. If you think you found a solution that doesn't have these issues (which is entirely possible!), I recommend to send it to the mailing list. It can really make a difference there! (Unlike here on TH-cam. 😉)
@@nipafx Thanks for the link. It seems what I was trying to argue for is called "target typing".
With the raise of AI and the need for strong textual support, this is a real let down. From my own experience, my team and I were heavily testing with new ideas with processors and API design and personal I think this sets back Java a couple years in making it a "better choice" for new developers. The world of development is moving away from hassling with code to more of a friendly (get the job done) experience, Java keeps showing it's disdain for fun.
That was a special video just like your explanation ♥
We trust Java architects are going to propose something great like they always did for past three decades
like fucked up generics?
@@guai9632 What's wrong with them
@@mralix9566 in kotlin they made them right, you declare variance of a generic parameter once. if the class is both covariant and contravariant on the same parameter, you have to introduce two interfaces. this makes generics much less verbose and easier to use. in java you have to declare variance on every method. as a result, in kotlin skilled dev can design generic api once and then less skilled devs would just use it barely noticing. in java everyone has to deal with them leading to more confusion and bugs. some teams even chose not to bother with generics at all, and you'll have less expressive apis in the end
I guess they didn't want to redesign again their new and shiny collections, which they designed mutable by default. mutable collections are an example of both co- and contravariant type and had to be redesigned if they went the kotlin way from the start
also there is type erasure. usable metainfo just absent from the class files and one cannot get it back via reflections. thus poorer metaprogramming
also primitive generic params have to be boxed, and it's slower
Why not treat templates similarly to regex patterns? Something like Template t = String.compile(`Hello, @{name}!`) Then you can run t.process("world") to get the result.
It was the right call
If syntax is going to be a regular method call, I'm definitely in. This is highly subjective but somehow `STR."..."` syntax is hard to read, it just puts too much focus on the STR rather than string content itself. I think the syntax does matter.
Idea of `String.interpolate("Whatever \{foo}") is not too bad. Let's see what it is going to eventually become.
BTW: Only JS uses dollar sign? Perl, PHP, Bash, Groovy, Scala, Kotlin,.. (yeah...)
My guy used every single place inside his apartment to film 😅
Technically, the hallway was left unrecorded, but it has terrible lighting. :D
StringInterpolatorFactory(new StringTemplate(new Thread()).interpolate(new StringExpression("/{value}"), new StringTemplateParams()).build().toString(). That's how to make it entetprisely.
😂
I really wished they wouldn't have use \ for escaping. It's just so cumbersome to type on a german keyboard. i get the backwords compatibility aspect of it. I just hpped they would have considered the internationalizational aspect of that feature.
Specifically on a German keyboard, this argument seems so strange to me! 0, =, ß, ?, ` are all frequently used characters and they're all right there on the same or neighboring keys. Are you really saying that you embed so many variables in strings that it will significantly increase your use of those keys, overshadowing `=`? Also, \{ is only one modifier whereas ${ are two, which makes it feel much more cumbersome to me.
Not sure why you're complaining about the backslash given how hilariously bad the placement of the curly braces is on the German keyboard.
@@nipafx The number of variables embeded in string qould increase significantly if String templates would have made it as a full feature. But that is not my point. If you look at the american keyboard layout, frequently used characters in programming like \, [, ], /, ` etc are primary characters, meaning you do not need to hold another key to type them. On the german keyboard, these are either secondary or tertiary characters, so you need two or more key additionaly to type them, which in my optinion makes them automatically more cumbersome to type.
I am sure there are other keyboard layouts with similar issues with different characters, and you can not accomondate all of them, but by using the backslash it seems like the designers were only looking at the american keyboard layout and did not consider the typing experience on other layouts.
I liked String Template
Same.
Can we get a video on why not valhalla now?
No need for a video: "It's complicated work and not the only / most important thing that's happening right now. It's ready when it's ready - hopefully soon." There you go, video avoided.
PS: Trust me, there are very few people in our community that want it to happen NOW more than me. 😖 th-cam.com/video/kzjGp7LmW0I/w-d-xo.html
@@nipafx I thought it would be neat to explore some of the challenges and seeing some things that people tried but decided it was not the best idea.
@@percival477 A Valhalla history lesson? Not a bad idea, but challenging. If you want to look into it yourself, search for "Brian Goetz Valhalla" and pick some of the presentations, e.g. th-cam.com/video/1H4vmT-Va4o/w-d-xo.html
JavaScript may be the only CURRENT top ten Tiobe language to use ${}, but there are plenty of us who write bash scripts, some who use Groovy directly or indirectly (e.g. Gradle), and some poor, unfortunate folks who use PHP. For better or worse, PHP was a top 10 language.
Not to mention the second and third most used JVM languages: Kotlin and Scala. They sure go out of their way to avoid recognizing their existence...
Why we can not use %s{} as a combination of existing string format syntax and new possibility? We can even have %{} for cases when we do not want force processor to interpolate value as string and give it ability to decide which representstion is better.
I prefer the %{someVar} syntax.
For the exact same reason we cannot use $
Every syntax that can appear today in a valid Java string literal suffers the same backward-compatibility problem. \{} is better because no existing string literal can contain it.
Enjoyed the video and learned a lot about the state of string interpolation. However, the arguments presented against the dollar sign as a special character in string interpolation are extremely weak. First, devs would use string interpolation 100x or 1000x times more often than a currency indicator or whatever other purpose it is used for. Second, while someone's top 10 languages list may only include one that only uses dollar sign interpolation, that one is used in 99% of all web applications. That's like saying that of the top 10 substances found in the ocean, only one is water. Not to mention that there are two close cousins to the top 10, namely Typescript and Groovy, that use dollar sign and curly braces for string interpolation.
The point about water is pretty good - made me chuckle. 👍But what about 99% of all system code being written in a language that doesn't have any interpolation? There is zero water in... (well, that's actually unfair because water is everywhere) ... the sun, there's zero water on the sun. So I can apply your logic and then we don't need string interpolation? 😉 What I'm trying to say is that across all languages, interpolation by dollar sign is far from ubiquitous.
We don't agree on how strong the arguments against $ are but we seem to agree on there being some. Given that I've heard none in favor, \{ still seems to come out ahead.
Now, StringTemplate could have a method to turn itself into an interpolated string.
Yeah, in fact they already did have that in JDKs 21 and 22. I didn't use it at 10:33 because it favors one out of all possible "StringTempalte -> ..." transformations. E.g. `Statement.create("text \{variable}")` would then be harder to discover and longer than `"text \{variable}".interpolate()`, which I don't find ideal.
What's wrong with String.format()?
Syntactically it's incovenient that the placeholder and the variable are so far apart, performance-wise it's just slow compared to concatenation, and from a security point of view it lacks the capability to apply format-specific rules (e.g. SQL, JSON, etc.) before user content is interpolated into the string. Not all of those issues matter in all situations and `String::format` is definitely ok to use (I do it a lot and generally prefer it over string concatenation), but there's room for improvement.
It is damn expensive.
I wrote an alternative implementation using an iterative approach, instead of transforming the format string to an object presentation at first.
That performs ways faster, but with the downside, that it may output some part of the result at first, before failing due a syntax error.
Furthermore, in my humble opinion, String.format() is overbloated with much too many features. In 99.9% of all cases people are just using "%s".
@@peacemakerle Can't confirm the 99.9% - maybe 1-2% would be `%d`. 😂 Otherwise true. 👍
I'm glad they ditched that ugly implementation of string template
Two toothbrushes! Girls! This one taken 🎉
Offtopic: Year 12,024, Nikolai? Kurzgezagt mich! 😆
😁
I don't understand why you can't just start with both the triple-quote """ and the \{var}, and then leave the rest of the crap out! Those two compiler-syntactic structures seem to capture the essence of what Java is trying to accomplish here. I mean, I will admit I haven't even used these templates yet, but the value of it all looks (to me) like it can be summarized in those two features. After that - adding "RAW", "STR", "FMT", and "ARBITRARY" is where the actual "featur-itis" starts to occur. - Please disagree with me. Sincerely, Ralph
var s = """\{var}""";
What type is `s`?
"It is a non-goal to perform an altered version / Syntactic-Sugar for String Concatenation" ... Take that out of the JEP. That's my suggestion.
@@nipafx Well ... Clearly the answer isn't `java.lang.String`, or you wouldn't have posted this as a reply. Ummm... So... May I ask what on earth is preventing the answer from being `java.lang.String`?
@@rtorello75 Hey, you're designing this language feature, it can be whatever you want. 😉 `String` would absolutely work. What would the effects be? Every Java developer would be a bit happier when mixing strings and variables - that's nice. But we would've done nothing to reduce the prevalence of a security problem (specifically, injection attacks) that is a serious problem in our industry and causes some of the applications these developers write to lose all their user data. Oops.
What if we instead find a way to make this new feature more elegant than concatenation (so developers will actually use it) but as safe as The Proper Way to combine strings and variables? (What exactly that is depends on the domain, but for, e.g., SQL it would be prepared statements.)
We need interpolation, pretty please, ok?
You're nicer than the person I portray at 5:20 but everything I say in that section applies to your request. TL;DW: The mild inconvenience of typing ` + ` is orders of magnitude less important to fix than the security issues caused by injections.
Just keep trying. It's better to not add it if you are doing it ugly.
If only there was any language in the JVM world that did have an interpolation working elegant and secure for years. That would’ve made all of these arguments against templates and interpolation quite awkward. Luckily, we live in 2001 and Scala hasn’t been invented yet.
I don't recall a single argument against templates and it seems Scala had the same thoughts on interpolation or they wouldn't have picked the approach they did. So on those two topics Scala and Java agree. And even Scala's solution and Java's retracted proposal are very similar. I think the main difference is that Java balked at the weird syntax, something that never bothered Scala.
@@nipafx would do you mean by “weird syntax”?
Here’s an example of valid Scala code
s”Hello, World! 1 + 1 = ${1 + 1}”
sql”insert into users (name, age) values (${user.name}, ${user.age})”
The second one needs a library though, but it’ll create SQL statements and handle escaping for you. If that looks weird, I’d be happy to see not-so-weird Java version of examples above
@@nikitamyazin6586 Have you ever called a method in Java with `method args` without parenthesis? The non-weird way would be `sql("...")`. A lot of people, Java users as well people working on the language, were uneasy about introducing an additional, one-off method invocation syntax. (Personally, I didn't mind that much.)
@@nipafx for me that sounds like an issue with people that don’t want to learn anything new. Programming languages should evolve over time, you can’t make them meet modern expectations based purely on ideas that existed 30 years ago. So while it’s valid a concern, it shouldn’t be a show stopper.
@@nikitamyazin6586 It's not a show stopper - it was proposed like that after all. But it's a downside of the proposal. And I think it's you who doesn't want to learn anything new (if you balk at that statement, you were just as unkind to other people), in this case the considerations behind designing a language and the benefits of conceptual simplicity.
the character to use in template does not really matter.
The bad part is the STR.""
The only good way is to be able to do "my \{variable}" and to be able to pass it every where I can pass a String.
We don't want to call toString() every time we want to use it, this should be a "String" by default nothing else.
The section starting at 5:20 was made for you!
java keeps pretending it's the only language on jvm
both kotlin and groovy use dollar sign, so we won't
Or Kotlin and Groovy language designers made mistakes (just like Java designers did, btw) and we can do better. 😉 I think that possibility is at least worth exploring.
kotlin and groovy designers know well what a principle of least surprise is
@@guai9632 And Swift, Python, C#, ... designers don't? Also, do you think this should be the only consideration or is there a trade-off?
c#'s do
@@guai9632 Leaving aside that you left ~1.67 of my questions unanswered 😉, why doesn't C# use ${var} or $var for embedded variables, then?
This is really not cool. I now have to go and update all code bases where I already introduced this.
You sound like you are a bit under the weather, take a sick day and take care of yourself.
I will, thank you. :)
Why not just `\{var}` like javascript?
See 5:20
i hated the "\{}" format. i am glad it got removed.
In case you didn't watch the whole video, you probably wanna watch the two minutes starting at 7:35. 😬
Why don’t do the whole mess like in Kotlin. That’s pragmatic enough!
This 5:20 you?
لقد كانت من اهم الخصائص المفيدة... للاسف😢
I don’t understand why Java cannot keep it simple
Because Java dev want a high retrocompatibility and a good safety. That's why we use Java in enterprise software
@@pockpicket9360 i don’t think that this is a problem. Backticks could be enough and simple $ interpolation is enough what most of us need
dudes ... just slow down the tempo
So it won't be re-introduced as a Java 24 JEP? Really? You are kidding, right?
A lot of us who want string templates will be stuck on Java 22. for a while ... Thank you Oracle, you could not just ship the feature "as is" in Java 23 without officially listing in the JEPs list?
If you're stuck on any version, please don't make it 22! I'm not aware of any vendor providing updates for that after September. If you absolutely have to, you can use the feature just the same on JDK 21.
More importantly, though: If you committed to a preview feature so hard that you're now stuck on a JDK release, you're doing it wrong. You must've ignored _all_ the warning signs - the barrier tape, the blinking red light, the sirens, the people in yellow vests hectically yelling and waving at you from afar... They were all trying to tell you to never write more code against a preview feature than you're willing to throw away and rewrite.
Cough *kotlin* cough
The real problem is all those “Java Neanderthalers” who specify the java heavy syntax - kick them out!!!
No one cares about this security bs, just give us interpolation
Strong disagree. I was looking forward to a nice way to not have to think about SQL injection risks every time i write an sql query with dynamically included parts.
One of the main benefits of Java is security.
That opinion is exactly why simple string interpolation is dangerous and won't be introduced in Java.
@@shadeblackwolf1508 But the thing is that most SQL library APIs use positional/named parameters, so it's not really a security problem as you say. Saying string templates are there for security also is not good enough of an argument. String templates/interpolation should be there for convenience and not for security. Security aspect is already handled by widely used SQL libraries.
@@behindthemind1825 the security argument is the reason the feature is considered at all. If it gets fully scrapped, interpolation isn't coming.
I think java is not between safe hands.
The java community process is one of its kind. Moving an important language is hard. The last 20+ years Oracle and the java community have done (remarkably) well in my opinion.
@@MeriaDuck what you said is correct. I started working with Java 6 and java 7 and thing went really well recently.
But some features are really needed for the language such as ?. (that returns null instead of NPE) string templates as any other language. rethink getters/setter (so we don't have to use lombok). default parameters for methods and constructors. I know this is not easy because of backward compatibility but people are still using Java 7 and 8 anyways.
I mean we should not be afraid to break things if we want java to live in this era.
@@ramdaneoualitsen1323 many of those features are available on the JVM in the form of kotlin. Java may or may not follow everything that is fun in Kotlin
if you're going to use backticks instead of double quotes then \{} is unnecessary. You can just use \variable
I think that would
ot always work well.
@@TheBigLou13 parsing rules could be completely different in backticks
@@bluemeriadoc But then users have to learn two completely different rulesets for what's essentially the same thing: a string of characters. And the sole benefit is a little less typing - and of curly braces of all things, which Java devs already have on speed dial. 😉
@@nipafx which is why using backticks is dumb
@@bluemeriadoc I'm not convinced of backticks either. I think "..." with some prefix would work best. I just used backticks in the video as the simplest-to-understand example syntax.