When I saw Python was gaining pattern matching, the first use case I thought of was Option¹ & Result² types, but I haven’t seen them mentioned yet in the discussions on What We Can Use Pattern Matching in Python For. Which surprised me, because I thought a use case so common in other languages (my personal experience is with Rust and Elm) would have been mentioned by now.
¹ Option[MyType] = Some(my_value) / None
² Result[MyType, MyErrorType] = Ok(my_value) / Err(my_error_value)
Both have a usage pattern that you see in most pattern-matching use cases: choose a code path based on which variant you’ve got (e.g. Ok/Err); subsequently work with the value wrapped by the variant. Pattern-matching lets you do both at once, so, yay ergonomics – until you realize that a match statement does in ~five lines what if x is None / return / continue processing does in ~three.
# traditional
# name: Optional[str], i.e. 'my name' or None
if name is None: # Can't omit this, mypy will complain
return None
return name.upper()
# modern cover
# name: Option[str], i.e. Some('my name') or Empty
match name:
case Some(x):
return Some(x.upper())
case Empty:
return Empty
So maybe what I like about Option&Result is not that they enable pattern-matching usage – it’s that I know them from Rust, where the type system is not optional, and so type-correctness guarantees are pervasive. Move the pattern to Python, and maintaining pervasive type-correctness starts looking a lot more like work.
But then I hit an example that Option[T] can do, and Optional[T] very much can not: using the Option.map method. Empty.map(f) exists just fine and returns Empty. None.map(f) could never, because None does not have methods.
# name: Option[str]
# Works whether name is Some('my name') or Empty
return name.map(str.upper)
^ Nice, no? So now I’m just about convinced that bringing Option & Result to Python could actually be useful, and is not just noodling in the margins. More of Patina’s Option API here. And that you can end with pattern-matching on case Some(x): is just a bonus.
When I saw Python was gaining pattern matching, the first use case I thought of was Option¹ & Result² types, but I haven’t seen them mentioned yet in the discussions on What We Can Use Pattern Matching in Python For. Which surprised me, because I thought a use case so common in other languages (my personal experience is with Rust and Elm) would have been mentioned by now.
¹ Option[MyType] = Some(my_value) / None
² Result[MyType, MyErrorType] = Ok(my_value) / Err(my_error_value)
Both have a usage pattern that you see in most pattern-matching use cases: choose a code path based on which variant you’ve got (e.g. Ok/Err); subsequently work with the value wrapped by the variant. Pattern-matching lets you do both at once, so, yay ergonomics – until you realize that a
match
statement does in ~five lines whatif x is None / return / continue processing
does in ~three.So maybe what I like about Option&Result is not that they enable pattern-matching usage – it’s that I know them from Rust, where the type system is not optional, and so type-correctness guarantees are pervasive. Move the pattern to Python, and maintaining pervasive type-correctness starts looking a lot more like work.
But then I hit an example that
Option[T]
can do, andOptional[T]
very much can not: using theOption.map
method.Empty.map(f)
exists just fine and returnsEmpty
.None.map(f)
could never, becauseNone
does not have methods.^ Nice, no? So now I’m just about convinced that bringing Option & Result to Python could actually be useful, and is not just noodling in the margins. More of Patina’s Option API here. And that you can end with pattern-matching on
case Some(x):
is just a bonus.Doesn’t python already have Optional[] and co in the type hints library?
Edit: Yep
From PEP 484.
So I guess, be careful using this with
typing