4 ms·
Python pattern matching: Guards and or-patterns might just not compose well
- munro 6y ago#![feature(or_patterns)] // Prompt the user whether they want to accept the match pub fn check(x: i32) -> bool { use std::io::{stdin}; println!("Checking this match: {}. Should we accept it? y/n", x); let mut s = String::new(); stdin().read_line(&mut s).expect("Did not enter a correct string"); return s.trim() == "y" } pub fn main() { match (1, 2) { (x, _) | (_, x) if check(x) => { println!(":)") } _ => { println!(":(") } } } Reading this really hurts my head, it's so bizarre seeing x used twice, and the if expression called twice for each x. Even the author calls this weird, why would anyone want this?! https://rust-lang.github.io/rfcs/2535-or-patterns.html https://rust-lang.github.io/rfcs/2535-or-patterns.html Reading the RFC, it seems like didn't intend for the syntax to be abused like this, so perhaps it needs some refining. The RFC shows much more immediately understandable examples of or_patterns, which does look really nice. pub fn is_green(self) -> bool { match self { | Tile::Suited(Suit::Souzu, 2 | 3 | 4 | 6 | 8) | Tile::Dragon(Dragon::Green) => true, _ => false, } }
- mar77i 6y agoI wonder why anyone would think inverting semantics like this was anything but asking for disaster. With all the metaprogramming that is possible, will the matching Cat(age=age) even produce a coherent object that has an age argument passed to __init__? Do keyword arguments in those patterns work on properties? How will it compare to another cat, is that using "is" or __eq__? Does Cat have to derive from the same type object? def Cat(**kwargs): return type("Cat", (), {"__init__": lambda self, **kw: ([setattr(self, k, v) for k, v in kw.items()], None)[-1]})(**kwargs)
- heavenlyblue 6y agoHave you read the RFC before posting this? There’s a magic method called “match” that you can override to support matching.