It's not silly at all, but useful. For example, consider fn foo(Wrap(x): ...)
or fn foo((Ok(x) | Err(x): ...)
.
Yeah, so Rust managed to avoid the usual pitfall of if x = 42
, so it shouldn't need Yoda conditions... and yet we still have them. I don't think that's good.
It would probably make sense to continue allowing it for code generation purposes. Suddenly failing to compile Yoda patterns would probably introduce a non-uniformity that would in turn require many macro authors to come up with special cases.
Oh, I didn't suggest we disallow it. We also allow if 42 == x
, after all.
I just really dislike it being idiomatic for hand-written code.
I didn't mean the Yoda condition is good -- I was just amused to make the connection. Overall it's a natural edge case for pattern matching though. You can also write a constant let
when it's irrefutable, like let () = println!(...);
, which is only useful to statically assert the fact that it is constant.
I'm with this guy
I see a lot of questions about more complex syntax and determining scope and whatnot. What if we started by implementing only the minimum-viable syntax (if $expr is $pat {}
) and disallow anything more complex at first? This simple form has obvious semantics and would satisfy the 90% use-case right away, and we can worry about how/whether to extend it later.
This was the same approach taken for if let $pat = $expr {}
—we deferred dealing with &&
and other more complex syntax until later
Because that has no significant advantage over matches!()
.
Note that at this point the thread is very much repeating itself:
So someone with more free time than I currently have (sorry! ) should probably put up an RFC that spells out the argument: "let's stabilize Never mind, I completely missed that this is being stabilized.matches!()
since everyone wants it, and no one's been able to come up with a compelling variable bindings story, or any other reason to provide this functionality via a new is
keyword".
matches!
is already stable in 1.42-beta.
It has no significant advantage in the same way as for
-loop has no significant advantage over an explicit loop
over an iterator. In other words: yes, it's a sugar construct, but which is significantly easier to type, read and perceive over matches!()
("natural to read" property is quite a nice one). Considering that it covers a sufficient fraction of use-cases, I believe at the very least it's a proposal worth consideration.
Personally I wouldn't be against it, but on my list of "nice to have" features it's quite low.
See:
Bindings are a significant improvement. To put it into code, with is
you can do this:
if opt is Some(x) {
println!("We got ourselves a {}", x);
}
Correct me if I'm wrong, but that's not possible with matches!()
. That is the shortcoming we're talking about.
But that can be done with if let
Yes, but now we're back to yoda conditionals.
if let 42 = x {}
I guess this really is going in circles I'll abstain.
So just use if let
with binders and matches!
without binders, then?
That seems like a reasonable approach to me, anyway.
To my mind the feature that's really missing is let-else:
let Some(x) = x else {
return Err(something_complicated(y));
}
// x is unwrapped here
// compile-time error if this point is reachable from the else block
I know this has been discussed before but I don't know what, if any, conclusions were reached and it's hard to search for.
TL;DR obvious syntax is ambiguous (sadly), focus is on if-let chaining currently (positive case), then potentially moving to the negative case. There is a draft that consistently allows "`let as a boolean-evaluated expression".
Nitpick: "equals" is how I'd read ==
; let ... = ...
should be "let ... equal..." (no 's').
Ah, true. "if let forty-two equal x"
On topic, I don't really think we need an is
operator, since if-let already works for those usecases anyway, and for simple matching (assuming you don't want to use a constant let, since it reads weirdly: if let Some(42) = x
), there's matches!()
, so I'm not sure is
is worth cluttering the syntax with. Unlike with ?
and try!()
, I don't think this is a really common thing.
I'm tempted to use matches as is;
--> is!(x, 42)
Heh, is that allowed under current macro import semantics?
is
seems confusing to me, given that in Python (and I think some other languages) it refers to referential equality, which is very different from pattern-matching equality.
And, as mentioned above, introducing new bindings is done with let
. The only exceptions I can think of are function arguments and globals. It would be good to maintain this consistency.