4 ms·
Unpleasantly verbose, especially compared to Kotlin. They'd have come up with a much better approach if they had to add it to their list of current implementati
by david_allison 3y ago
Unpleasantly verbose, especially compared to Kotlin. They'd have come up with a much better approach if they had to add it to their list of current implementations.
C# $"{x} plus {y} equals {x + y}"
Visual Basic $"{x} plus {y} equals {x + y}"
Python f"{x} plus {y} equals {x + y}"
Scala s"$x plus $y equals ${x + y}"
Groovy "$x plus $y equals ${x + y}"
Kotlin "$x plus $y equals ${x + y}"
JavaScript `${x} plus ${y} equals ${x + y}`
Ruby "#{x} plus #{y} equals #{x + y}"
Swift "\(x) plus \(y) equals \(x + y)"
Java STR."\{x} plus \{y} equals \{x + y}"
- rthkljlkrj 3y ago[dead]
- wiseowise 3y agoThere's literally two sections explaining why it is the way it is. > String interpolation is dangerous > Can we do better?
- ticklemyelmo 3y agoIt's not better though. The STR template processor behaves the exact same way as all the other examples, and it's the one that all the inexperienced devs prone to this kind of injection attack will use.
- wiseowise 3y agoThe approach of defining template processors is definitely better. Moving from unsafe to safe is "just" switching STR to whatever secure processor team writes.
- pron 3y agoThey won't use it if the APIs for generating HTML/JSON/SQL don't take String (or deprecate the old methods that do). The various APIs can support only their own, safe processors, and if an API doesn't take a String then you can't pass it interpolated strings.
- david_allison 3y agoBut they've made the common case much worse. For the 'injection' case, they could define an annotation which stops interpolation on a provided parameter, and provide a more verbose method to handle templated interpolation correctly. A sample syntax by JetBrains is below. [0] In future, this could be leveraged to block/warn against dangerous interpolations @Language("SQL") // This adds SQL highlighting, encouraging developers to use it String query = "SELECT * FROM Person p WHERE p.last_name = '${name}'" // future warning/error [0] https://www.jetbrains.com/help/idea/using-language-injections.html https://www.jetbrains.com/help/idea/using-language-injection...
- djha-skin 3y agoYeah that's great for new code. What about all the old code people have written and they want to upgrade to the new version of the language? `\{` used to be invalid syntax for the string, so if they add meaning to that syntax then it won't break old code. There's a lot of extant code for Java.
- masklinn 3y ago"IDENTIFIER, PERIOD, LITERAL" is also invalid syntax before this JEP, and it's the only way to enable string templates. The processing of untagged string literals is not changed.
- sesm 3y agoNote, that Java had to maintain backward compatibility, so they couldn't inject any new syntax into existing string literals. So, they had a choice between: 1. Introducing syntax for new kind of string literals (like JS did) 2. Make some kind of explicit function/constructor call (like they ended up doing). Advantage of 2 is that it doesn't require any new support from IDEs/parsers/code quality tools/etc. It is slightly more verbose, but not as verbose as some other Java syntax. IMO they've made the right decision.
- ghusbands 3y agoBut the solution does need support from IDEs and parsers. STR."\{STR."\{a}"}" is a valid expression, now, that uses a variable, and looks nothing like any previously valid expression. Given that it is an entirely new kind of expression, it's also unclear why they would choose \{ over { or need the dot. Is there some reason that they couldn't have chosen STR"{a}"?
- masklinn 3y agoExcept they did both: `\{` is not currently valid, so the "explicit function / constructor call" is completely unnecessary. Furthermore, they went on to use a printf-style formatting spec prefixing the template leader. > Advantage of 2 is that it doesn't require any new support from IDEs/parsers/code quality tools/etc. Of course it does, the sequence "IDENTIFIER, PERIOD, STRING LITERAL" is currently invalid, anything beyond a tokeniser should choke on it.
- deleted 3y ago[deleted]
- pron 3y agoBut the whole point of the JEP is to offer a different and better feature than string interpolation because the JEP claims that string interpolation should be avoided. Saying that using it for string interpolation is more verbose than the very thing the JEP tried to avoid doing is missing the whole point. The idea is that in the most important cases you should avoid the `STR` processor in favour of a JSON, HTML, or SQL processor. You can agree or disagree with the JEP's goal, but pointing out that the JEP manages to discourage the very thing that it sets out to discourage merely acknowledges that the goal is met.
- masklinn 3y ago> The idea is that in the most important cases you will not use the `STR` processor but rather a JSON, HTML, or SQL processor. That idea is evidently idiotic as demonstrated by javascript which has this exact feature, in a better form (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...): the most common template literals by far are untagged.
- pron 3y agoRight 'cause JS is so well-trusted with large, important server side software that it must be "evidently idiotic" not to follow exactly in its footsteps. Unfortunately, Brian Goetz and Guy Steele spat this one out off the cuff after only two years of study and experimentation with alternatives and failed to see that it's evidently idiotic; neither did most people who've used the feature.
- _old_dude_ 3y agoEven if I think that Guy Steele is a genius, an argument of authority is always a bad argument. Better listening to the foot soldiers than staying in your high tower. Using '\' instead of '$' does not allow $variable as a shortcut to ${variable} making the syntax objectively harder to read. Using '\' cleverly helps to detect when the processor is missing at compile time but it does not matter because the syntax mandates a big STR in front.
- somewhereoutth 3y agoCan I call out JavaScript for using backticks for a clean distinction between templated and untemplated strings: - no strange leading character(s) (per C#, VB, Python, Scala, and now Java) - templated strings are actually distinguished, so don't have to worry about accidentally running into template literals in normal strings (unlike Groovy, Kotlin, Ruby) - the distinguishing mark appears at the end as well as the beginning, for slightly better legibility. - Swift is quite nice in that the backslash is already an escape character for normal strings, so no issue with accidental use, but {} would have been a better choice than () as the former are rarer in normal strings.
- pron 3y ago> no strange leading character(s) (per C#, VB, Python, Scala, and now Java) There are no strange leading characters in Java, either. A template expression is a special case of an instance method call (it's a call to the `process` method on the template processor), and the "leading characters" are the same ones Java already requires for all instance calls. There's nothing strange about them; what is new (and therefore possibly strange) is the use of `"` for the method call instead of a method name followed by `(`. In other words, the new syntax Java added is what follows the dot in the method call to `process`; everything up to and including the dot is normal Java syntax. This is important to emphasise that a template string expression is an a method call that may (although normally shouldn't) even have a side effect. > templated strings are actually distinguished, so don't have to worry about accidentally running into template literals in normal strings Same here. `\{` inside a string remains a syntax error, as it always has been. Also, Java is typed (and the template expression requires a receiver of type StringTemplate.Processor) and there cannot be any ambiguity, and so it's unnecessary to introduce yet another punctuation mark. JS needed further distinguishing syntax because it is untyped.
- somewhereoutth 3y agoI understand what you are saying, but on the face of it we have: "my normal string" `my templated string` vs "my normal string" STR."my templated string" probably we can agree which looks cleaner (though I grant, maybe not as 'pluggable')