I think the issue is the order. Some(x) appiles first (check if value is a Some), then compute(x), and finally Ok(y) (check if compute(x) was successful). So we got this:
Some(x) if let Ok(y) = compute(x) => {
(1) (3) (2)
Of course - let-chains have the exact same issue...
To me, this makes perfect sense. You have the initial condition, then the "if let" which works like an if let. You do the compute, and filter the output, like a basic let statement but with a condition baked in.
It seems a little weird, but I've gotten used to it.
Shame that this proposal was so "controversial" that it kinda stalled.
It's sooo much easier to read.
And people try to convince us that reading from left then right then in the middle is better then just reading it from left to right...
I get that some wants to avoid having two ways of doing things in a programming language, but I don't buy this argument. If Rust would choose to have "await" keyword to not be a postfix operator it would be impossible to introduce it later. Even though it's much more ergonomic when writing chained code.
Hard disagree. The result of a computation is (not only in rust) almost universally on the left hand side of an expression. Having `compute(x) is Ok(y)` is completely backwards in that sense.
I mean, for loops also are just syntactic sugar, yet I wouldn't want to miss them. And it's not like they can't change it over an edition anyways if they really wanted to
I understand the code in the linked 1.88 release on let chains. But can you explain the order of execution for the given example in this release?
match value {
Some(x) if let Ok(y) = compute(x) => {
// Both `x` and `y` are available here
println!("{}, {}", x, y);
}
_ => {}
}
I'll spell out how I read it (after much thought, lol)
value is of type Option, right?
If it's None we go straight to the default case,
if it's Some we destructure to get the inner value into the x variable.
Now that we have x as a variable available we can call compute(x)
And only if computes returns Ok and not an Err do we jump into the body of the first match arm
And the check for Ok is also destructuring so we have y available, which is the result of the compute(x) call.
These come Haskell and from my experience they really do make code much nicer. I am worried that it's part of exhaustive checking though. (FWIW I'm not a Rust dev)
Here's the paper that discusses them: https://www.microsoft.com/en-us/research/wp-content/uploads/2016/07/pat.pdf
I've already been through my code and made use of let chaining where it made sense, and that was a nice improvement. Now I guess I'll be doing a pass for this. Probably a lot fewer places where I'd use it, but there will be places where it will significantly simplify things.
_xiphiaz@reddit
Might be just me but that
if-let guards in matchesexample goes over my threshold of readabilityTaldoesgarbage@reddit
Really? I kind of love them. I know that might be a controversial take, but I’ve been wanting them stabilized for a while.
pickyaxe@reddit
the controversial take is "aaaa this took me over 2 seconds to grok, it is unreadable"
somebodddy@reddit
I think the issue is the order.
Some(x)appiles first (check ifvalueis aSome), thencompute(x), and finallyOk(y)(check ifcompute(x)was successful). So we got this:Of course - let-chains have the exact same issue...
Taldoesgarbage@reddit
To me, this makes perfect sense. You have the initial condition, then the "if let" which works like an if let. You do the compute, and filter the output, like a basic let statement but with a condition baked in.
It seems a little weird, but I've gotten used to it.
robin-m@reddit
If we got an
isoperator instead ofif let … =, it would have been so much more readable:CichyK24@reddit
Shame that this proposal was so "controversial" that it kinda stalled.
It's sooo much easier to read.
And people try to convince us that reading from left then right then in the middle is better then just reading it from left to right...
I get that some wants to avoid having two ways of doing things in a programming language, but I don't buy this argument. If Rust would choose to have "await" keyword to not be a postfix operator it would be impossible to introduce it later. Even though it's much more ergonomic when writing chained code.
ParadiZe@reddit
i love rust and i agree with this, i get why its "if let" but "is" or "if expr matches patttern" would have made way more sense
blamethebrain@reddit
Hard disagree. The result of a computation is (not only in rust) almost universally on the left hand side of an expression. Having `compute(x) is Ok(y)` is completely backwards in that sense.
Noxitu@reddit
But pattern matching is one example where it is not the case. You don't do:
beephod_zabblebrox@reddit
thats similar to if and while though.
AresFowl44@reddit
Sadly
isisn't a keyword and I don't think anybody would have wanted to wait for an edition to do this change.robin-m@reddit
I do think that
iscould be a contextual keyword. If I'm not mistaken this would not be ambiguous. But anyway this ship has sailed long ago.umtala@reddit
why not? it's just syntactic sugar, not some urgent issue
AresFowl44@reddit
I mean, for loops also are just syntactic sugar, yet I wouldn't want to miss them. And it's not like they can't change it over an edition anyways if they really wanted to
braaaaaaainworms@reddit
people are using "is" as a variable or function name
StardustGogeta@reddit
Are you experienced with C#, by any chance?
I ask because the "is" syntax you propose here is very similar to the way C# does it.
I agree, it does seem more readable (or at least, more immediately intuitive) to me that way compared to the "let" approach.
robin-m@reddit
I've never wrote C#, but I think I saw this syntax in Herb Sutter cpp2 toy syntax experiment for C++, and he definitively knows C#
turunambartanen@reddit
I understand the code in the linked 1.88 release on let chains. But can you explain the order of execution for the given example in this release?
I'll spell out how I read it (after much thought, lol)
value is of type
Option, right?If it's
Nonewe go straight to the default case,if it's
Somewe destructure to get the inner value into thexvariable.Now that we have
xas a variable available we can callcompute(x)And only if computes returns
Okand not anErrdo we jump into the body of the first match armAnd the check for
Okis also destructuring so we haveyavailable, which is the result of thecompute(x)call.JeSuisAnhil@reddit
It's equivalent to this:
superstar64@reddit
These come Haskell and from my experience they really do make code much nicer. I am worried that it's part of exhaustive checking though. (FWIW I'm not a Rust dev)
Here's the paper that discusses them: https://www.microsoft.com/en-us/research/wp-content/uploads/2016/07/pat.pdf
PlasticExtreme4469@reddit
The simple example took me some time to comprehend too.
But chances are, you will get used to it and at that point, it will become a welcome sugar that makes writing reading code a tiny bit faster.
Karma_Policer@reddit
Code where they are needed is much harder to read without them. And usually less correct.
JeSuisAnhil@reddit
cfg_select!is a welcome addition.GhostPilotdev@reddit
Yeah, finally a cleaner alternative to the nested cfg attribute spaghetti. Been waiting on that one.
Dean_Roddey@reddit
I've already been through my code and made use of let chaining where it made sense, and that was a nice improvement. Now I guess I'll be doing a pass for this. Probably a lot fewer places where I'd use it, but there will be places where it will significantly simplify things.
BlueGoliath@reddit
Year of the furrylang.
programming-ModTeam@reddit
Your post or comment was removed for the following reason or reasons:
Your post or comment was overly uncivil.
Raknarg@reddit
this is Rust, not Go
BlueGoliath@reddit
Go devs dress up as gophers and engage in ahhh.... roleplay?!?!?!?
programming-ModTeam@reddit
Your post or comment was removed for the following reason or reasons:
Your post or comment was overly uncivil.
yowhyyyy@reddit
Surprised you had to mobility in your fat fingers to leave Phoronix to complain