5 ms·
I didn't realize how rich the normal match { } patterns can get until I saw these matches!() examples and was trying to figure out what that pattern syntax was.
by _bxg1 7y ago
I didn't realize how rich the normal match { } patterns can get until I saw these matches!() examples and was trying to figure out what that pattern syntax was. I've only ever used the basic enum matching/enum value unwrapping patterns.
- steveklabnik 7y agoIt can do a lot of stuff! https://doc.rust-lang.org/stable/book/ch18-03-pattern-syntax.html https://doc.rust-lang.org/stable/book/ch18-03-pattern-syntax... (This will need to be updated to include the things in this release, but I haven't gotten to it yet.)
- sdegutis 7y agoA similar macro the stdlib should have is poor_mans_cast!(foo as Bar::Qux) which expands to match foo { Bar::Qux(x) => Some(x), _ => None }.unwrap() which is a questionably-hacky way to cast to a specific enum variant. I've had to use it twice because I couldn't figure out a more Rust-like way to solve the problem at hand.
- steveklabnik 7y agoCould you maybe whip up an example on https://play.rust-lang.org/ https://play.rust-lang.org/ ? It's not 100% clear to me what you're doing here, but I'm interested!
- sdegutis 7y agoThink for example of implementing a list interpreter. In certain situations, you know for a fact that an AST node is a given type. So you just want to cast from Node to Node::Symbol(s) to extract that std::string::String out of it. RFC #2593 seems like it would help here, and is something I've wanted for similar but unrelated reasons. So in the meantime I made poor_mans_cast!() macro to do this, which I've used twice already.
- bombela 7y agoDid you look at the if let syntax? if let Bar::Qux(x) = foo { ... )
- _-___________-_ 7y agoIt looks like they want to panic if the variant is not what they expect. Basically implement their own unwrap() for their own enum, since the above logic is basically what Option::unwrap() does for Option::Some. Assuming there's not some wider design issue, I'd probably implement an unwrap_qux() method on the Bar enum
- dodobirdlord 7y agoI look forward longingly to the day when RFC #2593 comes to pass. https://github.com/rust-lang/rfcs/pull/2593 https://github.com/rust-lang/rfcs/pull/2593
- ojosilva 7y agoI'm actually planning on declaring war against pattern matching in EcmaScript, which is stage 1 right now. I can't believe how popular it can be. To me it looks like a huge antipattern, a complete different way of writing conditionals from ifs, built in a way that can lead to completely unreadable code (for complex matching) and very inconsistent behaviour. And just like switch-case, become something to avoid outside of byte-sized or plain literal matching. Not to mention how much each language differs in how the syntax and behavior is implemented, making it harder for beginners everywhere to ramp up. Like the smart-match clusterf* in Perl, pattern matching is just too darn clever for its own good.
- steveklabnik 7y agoInterestingly enough, I believe that the author of that proposal first learned pattern matching in Rust.
- dgb23 7y agoAny language feature can be misused. In my opinion JS doesn’t need it, because destructuring already exists for the case where you just want to be more expressive about extracting values. And it makes far less sense than in Rust where the type system enforces exhaustive matching.
- chrismorgan 7y agoFor reference, the proposal: https://github.com/tc39/proposal-pattern-matching https://github.com/tc39/proposal-pattern-matching Rust’s pattern matching is deliberately fairly limited in what it can do; it’s all about destructuring types, not running arbitrary code like Perl’s smart-match (which even so I would not describe as a disaster). It’s conceptually very clean—arguably simpler than what ECMAScript already has. `let PATTERN = EXPRESSION;`, `if let PATTERN { … }`, `match EXPRESSION { PATTERN => … }`, `fn NAME(PATTERN: TYPE)`, &c., everything that can introduce a new binding is a pattern. Some of the uses of patterns are refutable (match branches, `if let`, `while let`), and some irrefutable (`let`, `for`, function arguments, closure arguments). ECMAScript already has destructuring in various places, corresponding to irrefutable pattern matching; what the proposal’s `case` expression introduces is essentially just refutable destructuring, plus a smidgeon of expression-orientation (`->` corresponding to `=>`, that `case` is an expression that yields a value, rather than a statement) in a place that sorely needs it. This is a very logical extension of the language. If TC39 or equivalent were to design a new language to actively replace JavaScript (meaning something that all extant JavaScript code should be able to migrate to easily, preferably automatedly), there is no doubt in my mind that the language would be more expression-oriented than ECMAScript is, that destructuring syntax would be brought in line with what we call pattern matching so that there was one coherent concept underneath (probably called pattern matching), and that `switch` would use it, becoming equivalent to this proposal. The way people use JavaScript these days, these things are useful. (I write all this as an expert and heavy user of both Rust and JavaScript; I use JavaScript more, most of the time, but prefer Rust. Rust was the first language I learned with each of algebraic data types, pattern matching and expression orientation.)
- Measter 7y agoBehold: the dumbest stack-less postfix notation evaluator written purely to abuse that new pattern matching! https://play.rust-lang.org/?version=beta&mode=debug&edition=2018&gist=7aefe1ab0b8ece3adc864057cdcb0564 https://play.rust-lang.org/?version=beta&mode=debug&edition=...