> _Statement vs. Expression._ Some suggestions centered around the idea of making `match` an expression rather than a statement. However, this would fit poorly with Python's statement-oriented nature and lead to unusually long and complex expressions and the need to invent new syntactic constructs or break well established syntactic rules. An obvious consequence of match as an expression would be that case clauses could no longer have arbitrary blocks of code attached, but only a single expression. Overall, the strong limitations could in no way offset the slight simplification in some special use cases.
To give a concrete reason: Python's significant whitespace makes nested expressions much trickier to write/parse
I know which one I would bet my money on.
Entirely seriously, what are the trade-offs? I've heard general defences of it, for example nchammas's quote from van Rossum in a sister post to yours, but they all seem quite general—"it'll complicate things", but in a way that seems only to boil down to "it's unfamiliar and I don't like it." Which, to be fair, is van Rossum's prerogative to say—but it doesn't seem persuasive in light of general language design.
There are many situations where you want lots of branching because that's the problem domain, and trying to hide the essential aspect of the problem domain isn't helpful for code readability or maintainability.
If you are writing an interpreter, case statements are a natural thing. Yes, you can write that intepreter with expressions that are statements in disguise, but just because something can be done doesn't mean that it should be done. An interpreter is just a dispatcher waiting for some trigger from the outside and then firing off a command handler depending on the trigger. Just like a UI. GUIs are are also natural things to write with event driven patterns. If user clicks on box A, then do X, if User clicks on box B, do Y. That is a big case statement in disguise except the underlying framework handles that for you and you just write the code for X and Y. But if you didn't have that UI toolkit doing heavy lifting you would find yourself writing event loops and case statements to implement it as the most natural (non-ideological) solution.
Similarly, there are many situations where you want to handle exceptional conditions separately in a clear way that allows you to easily understand what the exceptional logic is and change it without touching the main processing flow at all. It all depends on the problem domain. Or the problem domain may require feedback where the handler tells the dispatcher to change the dispatch algorithm.
On the other hand, fluent APIs work well with streams of data that are processed sequentially. There the natural approach is to apply a sequence of functions to the stream. You want to avoid lots of nesting of case statements as the code would be ugly.
It boils down to minimizing complexity. You could write that event driven dispatcher as a function that takes as its inputs all the possible callbacks and the state of the world and spits out a specific callback. But that would be a more complex program that is harder to read and write, and thus is more error prone, regardless of the fact that in theory it is easier to refactor and unit test by dropping in a different function. In practice, it is not easier, it is harder. So when someone like Guido says, "it will complicate things", no it doesn't boil down to "I'm unfamiliar and don't like it", what it means is "I've spent a couple of decades writing code, have been up and down this road more times than you have, and I know it's a harder road to travel".
Yes but imo, Haskell (which has do notation) and Rust (where most things are expressions, but you still write them as expression statements when writing imperative code) actually have solutions to this problem. On the other hand, Python has a sharp divide between expressions and statements, so it needs strange duplicate forms of statements as expressions, like ternaries (if expressions but in a really weird order!) and lambdas (function expressions but your body is just an expression!)
> So when someone like Guido says, "it will complicate things"
Yes, it would complicate Python, which already has this division. In other languages, it's perfectly simple.
And, in the future, if Rust does get some kind of return-via-break for while loops (like it has for `loop`s) then there'll be less syntax to change.
No, as it's just an ideology, and not some absolute engineering truth.