7 ms·
It's fascinating how differently languages approach the string formatting design space. - Java's been trying to add f/t-strings, but its designers appear to be
by Mawr 2y ago
It's fascinating how differently languages approach the string formatting design space.
- Java's been trying to add f/t-strings, but its designers appear to be perfectionists to a fault, unable to accept anything that doesn't solve every single problem possible to imagine: [1].
- Go developers seem to have taken no more than 5 minutes considering the problem, then thoughtlessly discarded it: [2]. A position born from pure ignorance as far as I'm concerned.
- Python, on the other hand, has consistently put forth a balanced approach of discussing each new way of formatting strings for some time, deciding on a good enough implementation and going with it.
In the end, I find it hard to disagree with Python's approach. Its devs have been able to get value from first the best variant of sprintf in .format() since 2008, f-strings since 2016, and now t-strings.
[1]: https://news.ycombinator.com/item?id=40737095 https://news.ycombinator.com/item?id=40737095
[2]: https://github.com/golang/go/issues/34174#issuecomment-1450932232 https://github.com/golang/go/issues/34174#issuecomment-14509...
- oliwarner 2y agoIt's especially weird how hard people have to fight for string interpolation given it has had implementations since the 1970s. Even PEP 498 (fstrings) was a battle.
- bjourne 2y agoSuperficially f-strings reminds you of php and everyone remembers how awful that was. But Python's implementation is leagues better and we also have better tooling (ie smart parsers) for handling fstrings.
- dionian 2y agoLooks great - unlike java which is somehow recommending the format: STR."Hello \{this.user.firstname()}, how are you?\nIt's \{tempC}°C today!" compared to scala s"Hello ${this.user.firstname()}, how are you?\nIt's ${tempC}°C today!" STR."" ? really?
- nsonha 2y agoalso a syntax for braces that looks like escaping
- paulddraper 2y agoYeah, I hate to bikeshed, but this is the worst syntax possible without being a full-out prank.
- nu11ptr 2y agoValue types anyone? I have zero doubt it is tough to add and get right, esp. to retrofit, but it has been so many years that I have learned/discarded several new languages since Java... and they STILL aren't launched yet.
- mjevans 2y agoGo(lang)'s rejection makes sense. A format function that arbitrarily executes code from within a format string sounds like a complete nightmare. Log4j as an example. The rejection's example shows how that arbitrary code within the string could instead be fixed functions outside of a string. Safer, easier for compilers and programmers; unless an 'eval' for strings is what was desired. (Offhand I've only seen eval in /scripted/ languages; go makes binaries.)
- NoTeslaThrow 2y ago> A format function that arbitrarily executes code from within a format string So, a template? I certainly ain't gonna be using go for its mustache support.
- miki123211 2y agoIn many languages, f-strings (or f-string like constructs) are only supported for string literals, not user-supplied strings. When compiling, those can be lowered to simple string concatenation, just like any for loop can be lowered to and represented as a while.
- NoTeslaThrow 2y agoWhat's the risk of user supplied strings? Surely you know their size. What else is there to worry about?
- mjevans 2y agoMy reply was to the parent post's SPECIFIC example of Golang's rejected feature request. Please go read that proposal. It is NOT about the possibility of referencing existing / future (lazy / deferred evaluation) string literals from within the string, but about a format string that would literally evaluate arbitrary functions within a string.
- unscaled 2y agoThe proposal doesn't say anything about executing code in user-supplied strings. It only talks about a string literal that is processed by the compiler (at which point no user-supplied string can be available). On the other hand, the current solution offered by Go (fmt.Sprintf) is the one who supports a user-supplied format String. Admittedly, there is a limited amount of damage that could be done this well, but you can at the very least cause a program to panic. The reason for declining this feature[1] has nothing to do with what you stated. Ian Lance Taylor simply said: "This doesn't seem to have a big advantage over calling fmt.Sprintf" and "You can a similar effect using fmt.Sprint". He conceded that there are performance advantages to string interpolation, but he doesn't believe there are any gains in usability over fmt.Sprintf/fmt.Sprint and as is usual with Go (compared to other languages), they're loathe to add new features to the compiler[2]. [1] https://github.com/golang/go/issues/34174#issuecomment-1450932232 https://github.com/golang/go/issues/34174#issuecomment-14509... [2] https://github.com/golang/go/issues/34174#issuecomment-530131536 https://github.com/golang/go/issues/34174#issuecomment-53013...
- cortesoft 2y agoThen there is Ruby, which just has beautiful string formatting without strange decorators.
- bshacklett 2y agoThat tracks. Ruby followed in the footsteps of Perl, which had string manipulation as a main priority for the language.
- BiteCode_dev 2y agoDoes perl have lazy string processing? And I'm not talking about a coderefs hack.
- BiteCode_dev 2y agot-string are lazy, which is the point (escaping HTML, translating strings when you get preferred language headers, preparing SQL statements...). Does Ruby strings already allow lazy processing ? I'm not talking about wrapping them in a block and passing the block (all languages can do that with a lambdas) but a having literally that eventually resolves to something when you use it.
- psychoslave 2y agoThat's seems like the wrong pattern, maybe I'm missing something. Ruby has lazy evaluation with a generic lazy enumeration facility, whether to produce string or any kind of object. That is, I don't know what is the actual behavior of the default string interpolation in Ruby, but if profiling a codebase some string generation would gain lazy evaluation, there is a path to do so. But in the general case, does it really matter? Chances are good that a string construction is not a big bottleneck. Does Python miss such a feature of generic lazy enumeration, or is it so painful to use that some syntactic sugar felt like a must have? Genuine question here, I don't have any strong opinion on this t-string feature.
- BiteCode_dev 2y ago
- School-Cotton 2y ago> Go developers seem to have taken no more than 5 minutes considering the problem, then thoughtlessly discarded it: [2]. A position born from pure ignorance as far as I'm concerned There are a million things in go that could be described this way.
- unscaled 2y agoLooking at the various conversations involving string interpolation, this characterization is extremely unkind. They've clearly spent a lot more than 5 minutes thinking about this, including writing their own mini-proposals[1]. Are they wrong about this issue? I think they are. There is a big difference in ergonomics between String interpolation and something like fmt.Sprintf, and the performance cost of fmt.Sprintf is non-trivial as well. But I can't say they didn't put any thought into this. As we've seen multiple times with Go generics and error handling before, their slow progress on correcting serious usability issues with the language stem from the same basic reasons we see with recent Java features: they are just being quite perfectionist about it. And unlike Java, the Go team would not even release an experimental feature unless they feel quite good about it. [1] https://github.com/golang/go/issues/57616 https://github.com/golang/go/issues/57616
- mananaysiempre 2y ago> There is a big difference in ergonomics between String interpolation and something like fmt.Sprintf On the other hand, there’s a difference in localizability as well: the latter is localizable, the former isn’t. (It also worries me that I see no substantive discussion of localization in PEP 750.)
- lou1306 2y agoT-strings should also help localizability, you can now just retrieve them from a locale -> t-string mapping and they should Just Work. Or am I missing something?
- mananaysiempre 2y ago
- 1980phipsi 2y agoD had a big blow up over string interpolation. Walter wanted something simple and the community wanted something more like these template ones from Python (at least from scanning the first little bit of the PEP). Walter eventually went with what the community wanted.
- gthompson512 2y agoThis led to the OpenD language fork (https://opendlang.org/index.html https://opendlang.org/index.html) which is led by some contributors who had other more general gripes with D. The fork is trying to merge in useful stuff from main D, while advancing the language. They have a Discord which unfortunately is the main source of info.
- cherry_tree 2y ago>Go developers seem to have taken no more than 5 minutes considering the problem, then thoughtlessly discarded it The issue you linked was opened in 2019 and closed with no new comments in 2023, with active discussion through 2022.
- thayne 2y agoThat issue has a link to another Issue with more discussion: https://github.com/golang/go/issues/57616 https://github.com/golang/go/issues/57616. But as is all too common in the go community, there seems to be a lot of confusion about what is proposed, and resistance to any change.
- throwaway2037 2y agoI promise, no trolling from me in this comment. I never understood the advantage of Python f-strings over printf-style format strings. I tried to Google for pros and cons and didn't find anything very satisfying. Can someone provide a brief list of pros and cons? To be clear, I can always do what I need to do with both, but I don't know f-strings nearly as well as printf-style, because of my experience with C programming.
- theptip 2y ago_log(f”My variable is {x + y}”) Reads to me a lot more fluently to me than _log(“My variable is {}”.format(x+y)) or _log(“My variable is {z}”.format(z=x+y)) It’s nothing too profound.
- blami 2y agoI am not very familiar with Python. How do you localize (translate) first one?
- wzdd 2y agoYou don't with f-strings because they're substituted eagerly. You could with the new t-strings proposed here because you can get at the individual parts.
- BiteCode_dev 2y agoThat's what t-strings are about. They are lazy, so you can mark them for translation "as-is".
- Mawr 2y agoSure, here are the two Go/C-style formatting options: fmt.Sprintf("This house is %s tall", measurements(2.5)) fmt.Sprint("This house is ", measurements(2.5), " tall") And the Python f-string equivalent: f"This house is {measurements(2.5)} tall" The Sprintf version sucks because for every formatting argument, like "%s", we need to stop reading the string and look for the corresponding argument to the function. Not so bad for one argument but gets linearly worse. Sprint is better in that regard, we can read from left to right without interruptions, but is a pain to write due to all the punctuation, nevermind refactor. For example, try adding a new variable between "This" and "house". With the f-string you just type {var} before "house" and you're done. With Sprint, you're now juggling quotation marks and commas. And that's just a simple addition of a new variable. Moving variables or substrings around is even worse. Summing up, f-strings are substantially more ergonomic to use and since string formatting is so commonly done, this adds up quickly.
- lynndotpy 2y agoFor all its other problems, f-strings make Python such a pleasure to work with. C# has something similar IIRC.
- amitport 2y agoare you just going to ignore Javascript?