Using curly braces or parentheses to signify blocks of code is the trivial and natural way to implement a parser for a programming language. Doing anything else requires a conscious design decision and some effort and extra complexity. The C philosophy is to avoid complexity in the implementation in favor of a slightly more verbose language. The Haskell (ML) philosophy is the exact opposite. These design decisions have been cargo culted by later languages.
- make it easy to write and to read at the expense of having complexity in the parser / implementation. Programs (or documents) are written and read a lot of times, it's worth optimizing, as long as it does not make the implementation unmaintainable. I'm saying that as a writer of several manually crafted parsers.
- avoid ambiguities in the grammar at all cost. They just suck for every party involved.
As for indentation vs braces to delimit blocks, I practice both and don't really have any preference.
Copying and pasting python code is annoying (more so because it doesn't have macros or any metaprogramming really) and having to indent things in the python repl just feels dumb. I don't know anyone who thinks python does "well" in this area.
It does well but I'm not happy when I move code around and have to manually fix the indentation level at destination and check if I inadvertently broke an if or some loop. My editor does it for me with other languages and I have one less source of bugs.
VS Code tries to do it, but it’s heuristic based and generally fallible. (Disclaimer, work on vscode, not on python extension)
I much prefer working in languages wherein the series of tokens absolutely defines the semantics (as opposed to Python where the series of tokens + the context define the semantics)
Yep, but no editor can decide if the code must align with the last line of a loop or be indented out of the loop. I got at least one bug in production because of that, and a test that didn't catch the error.