String interpolation is one of those features like inference where if you've had it before then going without is very annoying, and so you add some and that's nicer, then you add more, each step seems like it's an improvement, and then one day you realise you're looking at unintelligible nonsense and you say "Oh no, what have we done?"
This is unusual, often CS would love to have as much of whatever as we can, but mathematics says no that's literally or practically impossible - but here both none and lots are awful and shouldn't be permitted.
One option, which Python and C# both picked is, well, leave it to taste. You can write sixteen pages of layered expressions in the uncommented interpolated string and it'll work, but your colleagues will curse your name and plot your destruction. Or at least you'll fail code review if you enforce such things.
Another option, in standard C++ 23 today for example, is refuse to take even the first step. You can have rich formatting, but standard C++ does not provide interpolation at all, if you want to format six parameters then pass them as parameters.
I'm happy with Rust's "Only a tiny bit of interpolation" where you can interpolate only identifiers, not any other expressions, but that's definitely more interpolation than some will be happy with, yet of course in some cases it's not quite enough.
Waterluvian · 46m ago
Purity and practicality are at odds and every language finds a different balance between the two. There is no one correct balance so busy minds will inevitably have loud opinions they want accepted as the one correct balance.
sublinear · 15m ago
> CS would love to have as much of whatever as we can, but mathematics says no
What does this have to do with either topic?
ejiblabahaba · 2h ago
Learned a few tricks that I'm sure are buried on fstring.help somewhere (^ for centering, # for 0x/0b/0o prefixes, !a for ascii). I missed the nested f-strings question, because I've been stuck with 3.11 rules, where nested f-strings are still allowed but require different quote characters (e.g. print(f"{f'{{}}'}") would work). I guess this got cleaned up (along with a bunch of other restrictions like backslashes and newlines) in 3.12.
F-strings are great, but trying to remember the minute differences between string interpolation, old-style formatting with %, and new-style formatting with .format(), is sort of a headache, and there's cases where it's unavoidable to switch between them with some regularity (custom __format__ methods, templating strings, logging, etc). It's great that there's ergonomic new ways of doing things, which makes it all the more frustrating to regularly have to revert to older, less polished solutions.
sfoley · 44m ago
Yeah I consider that one to be a trick question. I knew same-quote-style nested f-strings were coming, I just didn't know which version, and I still use the `f'{f"{}"}'` trick because I want my code to support "older" versions of python. One of my servers is still on 3.10. 3.11 won't be EOL until 2027.
nojs · 2h ago
> This is the first special feature of f-strings: adding a trailing equals sign lets you print out the expression and what it evaluates to.
>>> foo='bar'; print(f"{foo=}")
foo='bar'
Wow, never knew you could do that.
roenxi · 13m ago
And it seems like a bad idea because of that wow factor - it isn't really adding enough to justify having surprising behaviour. It is more likely to be a bug than a feature.
It'd be better to just let people implement their own function that prints a subset of locals(), or provide a standard function that does the same.
acdha · 37m ago
It makes me sad that the PEP for the equivalent behaviour for function keyword arguments wasn’t accepted. It’s really common to see foo(bar=bar) and I think it’s not only cleaner but would help see subtle differences if that was foo(bar=) because it would make the cases where some arguments aren’t simply being passed through more obvious: foo(bar=, …, baaz=baaz.get_id()) avoids the most interesting detail being easily missed.
carlhjerpe · 16m ago
Do you know why? I didn't know of the fstring one either but I've thought to myself across many languages that a way to print the expression (or just varname in my head) with the result should exist.
ck45 · 2h ago
Python release notes are really worth reading, for me there's usually some "positive surprise"
If you come from verbosity land C# release notes are magically good as well, always some way to reduce boilerplate while maintaining "implicit verbosity" which your proprietary LSP resolves 100% correctly.
I'd prefer writing C# if I had the Linux interaction libs Python has. I'm too dumb to write syscall wrappers
ahartmetz · 1h ago
Incredibly common for debug output. In C++, I have made it a habit to just copy the expression, once with quotes and once without. It's informative and doesn't require thinking, or, well, I'm still working on that.
stkdump · 1h ago
It's the kind of thing you do with macros in C++.
black_puppydog · 2h ago
such a boon for print(f) debugging. :)
jszymborski · 29m ago
No more will I have to
print("foo", foo)
psychoslave · 2h ago
Awesome, makes me glad I didn't touch Python for years now.
> makes me glad I didn't touch Python for years now.
C'mon, every language has quirks.
cluckindan · 2h ago
If this was JavaScript syntax, most of the comments would be lamenting the unintuitive syntax and weird features.
crazygringo · 2h ago
Right, I assumed the real point the quiz was making is that Python is as full of footguns as JavaScript, since I've seen this type of thing for JS a bunch of times.
Not saying I agree, but was definitely expecting that to be the main topic of discussion here...
jvolkman · 1h ago
But if it were Perl, they'd be celebrating.
neoden · 2h ago
How can I setup a linter to prohibit stuff like this in my code base?
One can question why python needs N built-in ways to printf with different syntax, different ways to escape things and different footguns.
Liftyee · 3h ago
I like this quiz format much more than just reading a doc because I get to guess what it might do before finding out, which reinforces how well I remember it. As a Python amateur I had no idea fstrings were so powerful!
frickit · 2h ago
These games just reinforce that I’m an idiot.
jdranczewski · 1h ago
I usually refer to https://pyformat.info/, which doesn't have all this detail, but most of the reasonable stuff is included
carlhjerpe · 37m ago
I really like the f"{ varname = }" syntax, didn't know about it before.
I have so much Python to learn, I scored 10/26
zahlman · 3h ago
21/26, with a couple of sleep-deprived brainfarts and a misclick. Learned very little, although I had the wrong reasoning for one of the ones I got right (tested afterward). I don't even use the {var=} thing or walrus operator, though.
I would definitely not do nearly as well on jsdate.wtf. I really still think JS has the greater WTFs.
the_mitsuhiko · 3h ago
I was not sure about the difficulty. Python has some really weird behaviors with some of the custom __format__. For instance f"{'None':<010}" will pad out, but f"{None:<010}" will error. The only one I ended up putting in is the gotcha that bool is an int subclass and gets the int behavior for custom format parameters (which almost sounds like a bug). f'{''''''''''''}' is also a weird one, but that is mostly an issue with the string concatenation syntax and not fstrings :)
There definitely are some more odd / confusing ones.
OJFord · 3h ago
> For instance f"{'None':<010}" will pad out, but f"{None:<010}" will error.
Is that any different than being surprised that 1 + 1 is 2 and '1' + '1' is '11'?
the_mitsuhiko · 2h ago
I don't know, but I find this quite confusing:
>>> f"{'42':<10}"
'42 '
>>> f"{42:<10}"
'42 '
>>> f"{None:<10}"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported format string passed to NoneType.__format__
(Or any other type. What can be padded is quite inconsistent)
OJFord · 1h ago
Ah I see, fair enough I suppose. Quite nice for catching bugs though to be honest - since you'll hit an error and realise you need to handle the None case appropriately, rather than a more subtle 'None' appearing somewhere bug.
lionkor · 2h ago
not really, since None stringifies to "None", so you would expect None -> "None" -> padding and whatnot added
stephenlf · 2h ago
Much easier than date.wtf
WithinReason · 2h ago
thanks I hate Python now
jvdvegt · 1h ago
Why would "0^5" evaluate to 5? (question 21)
And is there a way to link to a specific question?
palotasb · 1h ago
^ is the XOR operator, 0 XOR 5 is 5. (Exponentiation is *)
I made a mistake on 7, but wouldn't have done if I had syntax highlighting.
istrice · 3h ago
Nice quiz!
I admit I was surprised a couple of times (especially with f"{1<5:1<5}"), many of these features are hardly ever needed
serf · 2h ago
the reward for 100% should be a directory of languages that deals with strings in a sane/singular/readable way.
it's cool that half of those features are there. it's not cool that half the devs that read the thing after creation are going to have to look up the f string features.
Y_Y · 1h ago
I've compiled a directory of those lamguages here:
CivBase · 2h ago
16/26
I always use a reference when doing anything non-trivial with format strings of any kind and this quiz confirmed I should keep doing that.
Also I've been using Python professionally for over a decade but TIL about the Ellipsis object.
meinersbur · 2h ago
Just learned about the ellipsis statement and the !a modifier (I already knew !r and !s).
underdeserver · 3h ago
Cute quiz! As a reminder, if you're doing anything even slightly complicated with f-strings (beyond :x or var=), leave a comment.
elteto · 2h ago
Hey, I’m doing complicated things with f-strings so I’m leaving a comment as requested.
Disposal8433 · 3h ago
As someone who works on a codebase with almost no comments, please leave a comment for every block of code that does something and explain why (1 comment for every 5 or 10 lines of code should be fine).
Glad this is nowhere near Wat [2], though.
[1]: https://ezhik.jp/f-string.lua/
[2]: https://www.destroyallsoftware.com/talks/wat
This is unusual, often CS would love to have as much of whatever as we can, but mathematics says no that's literally or practically impossible - but here both none and lots are awful and shouldn't be permitted.
One option, which Python and C# both picked is, well, leave it to taste. You can write sixteen pages of layered expressions in the uncommented interpolated string and it'll work, but your colleagues will curse your name and plot your destruction. Or at least you'll fail code review if you enforce such things.
Another option, in standard C++ 23 today for example, is refuse to take even the first step. You can have rich formatting, but standard C++ does not provide interpolation at all, if you want to format six parameters then pass them as parameters.
I'm happy with Rust's "Only a tiny bit of interpolation" where you can interpolate only identifiers, not any other expressions, but that's definitely more interpolation than some will be happy with, yet of course in some cases it's not quite enough.
What does this have to do with either topic?
F-strings are great, but trying to remember the minute differences between string interpolation, old-style formatting with %, and new-style formatting with .format(), is sort of a headache, and there's cases where it's unavoidable to switch between them with some regularity (custom __format__ methods, templating strings, logging, etc). It's great that there's ergonomic new ways of doing things, which makes it all the more frustrating to regularly have to revert to older, less polished solutions.
It'd be better to just let people implement their own function that prints a subset of locals(), or provide a standard function that does the same.
The = support was added in Python 3.8: https://docs.python.org/3/whatsnew/3.8.html#f-strings-suppor...
I'd prefer writing C# if I had the Linux interaction libs Python has. I'm too dumb to write syscall wrappers
print("foo", foo)
Hell is paved with good will I guess. Probably Justine should update https://justine.lol/lex/
C'mon, every language has quirks.
Not saying I agree, but was definitely expecting that to be the main topic of discussion here...
I have so much Python to learn, I scored 10/26
I would definitely not do nearly as well on jsdate.wtf. I really still think JS has the greater WTFs.
There definitely are some more odd / confusing ones.
Is that any different than being surprised that 1 + 1 is 2 and '1' + '1' is '11'?
And is there a way to link to a specific question?
https://docs.python.org/3/library/operator.html#mapping-oper...
it's cool that half of those features are there. it's not cool that half the devs that read the thing after creation are going to have to look up the f string features.
I always use a reference when doing anything non-trivial with format strings of any kind and this quiz confirmed I should keep doing that.
Also I've been using Python professionally for over a decade but TIL about the Ellipsis object.
And for regex you have this in some languages: https://docs.python.org/3/library/re.html#re.X