5 ms·
One of my favorite things about Swift is its rich enums that (similar to Rust) serve as the building blocks for state machines. Swift has the advantage of expre
by oflannabhra 6y ago
One of my favorite things about Swift is its rich enums that (similar to Rust) serve as the building blocks for state machines. Swift has the advantage of expressive switch statements with pattern matching that have allowed me to simplify and condense the "which state should I go to next given x" type of logic.
I'm not trying to say Swift is better, by the way.
- estebank 6y agoHow is Swift's switch different to Rust's match?
- sullyj3 6y agoI don't think OP was necessarily claiming they were different
- oflannabhra 6y agoI'm not an expert in Rust, so some of these things might be available in it's match (just in a way I'm unfamiliar with), but for me the big advantages of Swift's switch are: - switching on tuples (not wrapped in a var): this prevents doubly-nested switches, which I've always found to be a problem in control logic. - unwrapping optionals - matching against an enum's associated value, and unwrapping it - using `where` clauses as part of the pattern - matching against type casts
- chewbacha 6y agoRust has all that functionality, but as the author mentioned, they avoided using enums and match statements because it led to more runtime errors and they were specifically trying to incur compile time errors. This is why they choose to use trait objects and type definitions to control state transitions. Edit: I invite you to learn more about the match keyword in rust and see how it relates to swift. I think you’ll find that it meets or exceeds your expectations: https://doc.rust-lang.org/book/ch06-02-match.html https://doc.rust-lang.org/book/ch06-02-match.html
- masklinn 6y agoAside from the last, this is all very standard stuff, I don't mean for Rust I mean for language with sum types in general. > - switching on tuples (not wrapped in a var): this prevents doubly-nested switches, which I've always found to be a problem in control logic match t { (Some(a), Some(b)) => a + b, (Some(a), None) => a, (None, Some(b)) => b, (None, None) => 0 } > - unwrapping optionals match opt { Some(v) => v, None => 0 } although it's common to use HOFs, the `?` operator, or `if let`. > - matching against an enum's associated value, and unwrapping it See above. - using `where` clauses as part of the pattern match opt { Some(v) if v > 5 => v - 5, Some(v) => v, None => 0 } > - matching against type casts Rust doesn't really do subtyping, so that's not a case which would come up. I guess the closest would be matching on the result of a downcast_ref (https://doc.rust-lang.org/std/any/trait.Any.html#method.downcast_ref https://doc.rust-lang.org/std/any/trait.Any.html#method.down...) but that just returns an Option so there's nothing special to it.
- discardable_dan 6y agoMostly match recurrence. One pain point about Rust is, due to its linear nature, you cannot use `as` patterns, such as: match e with x as (y, z) -> (x[0], x[1]) == (y, z) This is because the matcher itself must take ownership of the expression, and destructuring is an ownership transfer.
- kevincox 6y agoCan you point me to the swift docs for that? I don't understand what you are trying to do. You can bind references to what you are matching with @name. You also don't need to take ownership of a value. You can match on a reference to it with &. However without understanding your example it is hard to say for sure.
- masklinn 6y ago> You can bind references to what you are matching with @name. Given what they're saying I assume they're trying to match both the entire value and the sub-values e.g. xs@(_:xs') in Haskell. Stable Rust currently lets you use at-patterns and perform assertions on the sub-pattern, but not match there. > You also don't need to take ownership of a value. You can match on a reference to it with &. `ref` is what you'd use in a pattern though, `&` would deref' a reference so usually it'd be to Copy a Copy type which is provided behind a ref'.
- kevincox 6y ago> match both the entire value and the sub-values I see. Yes, it appears to be either-or for now. > `ref` is what you'd use in a pattern though Not in the pattern, in the "argument". Like this: https://rust.godbolt.org/z/eT366s https://rust.godbolt.org/z/eT366s pub fn f(v: &Option<String>) { match &v { other => eprintln!("Doesn't move {:?}", other), } }
- estebank 6y agoYou can do both. Your code is closer stylistically to what you'd want to use most of the time, but every now and then I encounter a case where using ref in a single pattern makes more sense.
- ragnese 6y agoThe only thing that that is bugging me at this very moment is that Swift's switch is a statement and not an expression. Ugh!