Because if I didn't misunderstood, this is not correct, is it?
NOT_FOUND = 404
OK = 200
match getCode():
case NOT_FOUND:
return default()
case OK:
return response()Because if I didn't misunderstood, this is not correct, is it?
NOT_FOUND = 404
OK = 200
match getCode():
case NOT_FOUND:
return default()
case OK:
return response()This along with mutable default values is going to be one of the nastier Python warts.
This is already special-cased in the standard library for, say, set union (where admittedly the concept is more similar to bitwise or).
Thanks for proving my point though!
match event.get():
case Click(position=(x, y)):
handle_click_at(x, y)
case KeyPress(key_name="Q") | Quit():
game.quit()
where `Click(position=(x, y))` is not at all what one would expect.What I still don't understand is: does the new syntax magically do this to a user-defined class? i.e. if I say
foo = Click(position=(x, y))
vs ...
case Click(position=(x, y))
those identical expressions, for the same value of Click, have widely different semantics?edit: typo fix
> Patterns may use named constants. These must be dotted names to prevent them from being interpreted as capture variable:
NOT_FOUND would always match as a capture variable, so you'd always return default().
I fully expect this to be covered by linters, but not with further language support.
NOT_FOUND = 404
m = {"NOT_FOUND": NOT_FOUND}
match value:
case m["NOT_FOUND"]:
pass NOT_FOUND = 404
match value:
case v if v == NOT_FOUND:
pass
On its own this is a convoluted alternative to `if`, but it can be useful when we have lots of patterns.Alternatively, we can avoid using a separate `v` variable and just use `value` directly:
NOT_FOUND = 404
match value:
case _ if value == NOT_FOUND:
pass
We can even match on a trivial value, and do all of the interesting checks using guards: NOT_FOUND = 404
match None:
case _ if value == NOT_FOUND:
pass
This latter form acts like Lisp's `cond`, and I've used it a few times in Scala, e.g. () match {
case _ if foo > bar => ...
case _ if foo < bar => ...
case _ if foo == bar => ...
}Yes! For the first 2 decades of its life, people loved Python because it was like “executable pseudocode”. Unfortunately over the last 5-10 years it seems to have given up on that idea, instead becoming more and more like “whitespace-sensitive C++”.
I agree; I was just trying to show how pattern guards work. I would only resort to pattern guards if I need a `cond` (like my last example), or on a few cases of a more 'natural' pattern match, e.g.
match foo():
case OK(msg):
return success(msg)
case NotFound(_) if isQuery:
return success("No results matched query")
case NotFound(msg):
return failure(msg)
...
If I were to implement your original example (i.e. 'which of these constants do I have?'), I'd probably still go with a "dictionary dispatch" (especially since it's an expression, so it works in lambdas, etc.): return {
NOT_FOUND: default,
OK: response,
}[getCode()]() (define not-found 404)
(match status
(,not-found (do-stuff))
(else (display "you might believe this is an else clause, but it actually just matches everything and binds it to else")))