PEP 622 introduced match
statement as an alternative to if-elif-else
. However, one thing I can't find in the proposal or in any of the material online is whether the match
statement can be used as an expression and not just as a statement.
A couple of examples to make it clear:
Example 1:
def make_point_2d(pt):
match pt:
case (x, y):
return Point2d(x, y)
case _:
raise TypeError("not a point we support")
Example 2:
match response.status:
case 200:
do_something(response.data)
case 301 | 302:
retry(response.location)
In the first example, the function returns from inside a case
clause, and in the second example, nothing is returned. But I want to be able to do something like the following hypothetical example:
spouse = match name:
case "John":
"Jane"
case "David":
"Alice"
print(spouse)
But it doesn't compile.
Not in Python.
In Rust and Haskell, matches are expressions composed of expressions:
let spouse = match name {
// expr => expr,
"John" => "Jane",
// expr => {stmt; stmt; expr},
"David" => {let s = "Alice"; println!("Matched David"); s},
_ => panic!("Unknown name"),
};
do
spouse <- case name of
"John" -> return "Jane"
"David" -> do
let s = "Alice"
putStrLn "Matched David"
return s
...so it's not technically impossible that the Python match
statement couldn't have been designed to work as an expression. Presumably, the reason it was avoided for Python are syntactical reasons:
Python does not have syntax for expression statements (e.g. {stmt; stmt; expr}
).
spouse = match name:
case "John":
"Jane"
case "David": # stmt; stmt; expr
s = "Alice"
print("Matched David")
s
Indentation to indicate a block being treated as an expression may look unnatural to some people. (See also: match
grammar.)
That said, it is possible your proposed syntax could be accepted in the future.