Can you give an example of something like this happening to the language? IMO 3.6+ brought many positive additions to the language, which I also think are needed as its audience grows and its use cases expand accordingly.
The walrus operator makes while loops easier to read, write and reason about.
Type annotations were a necessary and IMO delightful addition to the language as people started writing bigger production code bases in Python.
Data classes solve a lot of problems, although with the existence of the attrs library I'm not sure we needed them in the standard library as well.
Async maybe was poorly designed, but I certainly wouldn't complain about its existence in the language.
F strings are %-based interpolation done right, and the sooner the latter are relegated to "backward compatibility only" status the better. They are also more visually consistent with format strings.
Positional-only arguments have always been in the language; now users can actually use this feature without writing C code.
All of the stuff feels very Pythonic to me. Maybe I would have preferred "do/while" instead of the walrus but I'm not going to obsess over one operator.
So what else is there to complain about? Dictionary comprehension? I don't see added complexity here, I see a few specific tools that make the language more expressive, and that you are free to ignore in your own projects if they aren't to your taste.
> F strings are %-based interpolation done right, and the sooner the latter are relegated to "backward compatibility only" status the better. They are also more visually consistent with format strings.
No, f-strings handle a subset of %-based interpolation. They're nice and convenient but e.g. completely unusable for translatable resources (so is str.format incidentally).
`.format` lets you dereference arbitrary attributes and indices (I don't think it lets you call methods though), meaning you can run code and exfiltrate data through translated strings if they're not extremely carefully reviewed, which they often are not.
% only lets you format the values you're given.
> and isn't something like Django's _(str) better anyway
They're orthogonal. You apply string formatting after you get the translated pattern string from gettext. In fact, Django's own documentation demonstrates this:
def my_view(request, m, d):
output = _('Today is %(month)s %(day)s.') % {'month': m, 'day': d}
return HttpResponse(output)
What would "do/while" look like in Python? Since blocks don't have end markers (e.g. "end", "}", etc.) there's nowhere to put the while expression if you want the syntax to be consistent with the rest of the language.
This completely contradicts the rest of Python grammar, and indeed many languages’ grammars. The consistent way would then be `while x < 10` but that too looks ridiculous. The issue is that you can’t have post-clause syntax in Python due to its infamous spacing-is-syntax idea.
I'm not sure why the consistent way looks ridiculous.
do:
body()
body()
while x < 10
It's just a compound statement consumes the trailing while clause.
Decorators already precede a function (or class) definition[2], and one alternative for the ill-fated switch statement[1] was to have switch precede the case blocks to avoid excessive indentation.
So there's plenty of precedent in the other direction.
I think you're really stretching it when you say "there's plenty of precedent," arguably there is none as the decorator syntax is pre-clause and thus poses no indentation reading issues. So too for the proposed switch statement syntax. Then there is the fact that the decorator syntax is perhaps the most alien of all Python syntax, sometimes criticized for being Perlesque, perish the thought (on account of it being introduced by creative interpretation of a single special character though, so perhaps unrelated.)
My main gripe is the indentation. Your code reads as if the while condition is tested after the loop finishes. What if the while statement was part of the loop and could be placed arbitrarily?
do:
body1()
body2()
while x < 10
body3()
IOW `do:` translates to `while True:` and `while x` to `if not x: break`.
Addendum: I would also entertain forcing the `while` to be at the end of the loop -- as I'm not sure what this would do
Of course you can have post-clause syntax: if...else, try...except, for...else, etc.
(Edit: Actually, I think I know what you were saying now, and those aren't quite the same thing as they need a line after them.)
I do think the condition on the next line isn't the way to do solve this problem though (and I don't think it needs solving, while True: ... if ...: break does the job).
Why does `while x < 10` look ridiculous? It looks exactly like the syntax for regular while loops, just in this case it's after a `do:` block. And the example above yours looks like try/catch syntax, but tbh I like the one you suggested a bit more.
The walrus operator makes while loops easier to read, write and reason about.
Type annotations were a necessary and IMO delightful addition to the language as people started writing bigger production code bases in Python.
Data classes solve a lot of problems, although with the existence of the attrs library I'm not sure we needed them in the standard library as well.
Async maybe was poorly designed, but I certainly wouldn't complain about its existence in the language.
F strings are %-based interpolation done right, and the sooner the latter are relegated to "backward compatibility only" status the better. They are also more visually consistent with format strings.
Positional-only arguments have always been in the language; now users can actually use this feature without writing C code.
All of the stuff feels very Pythonic to me. Maybe I would have preferred "do/while" instead of the walrus but I'm not going to obsess over one operator.
So what else is there to complain about? Dictionary comprehension? I don't see added complexity here, I see a few specific tools that make the language more expressive, and that you are free to ignore in your own projects if they aren't to your taste.