csharplang
csharplang copied to clipboard
Champion: "&&= and ||= assignment operators"
- [ ] Proposal added:
- [ ] Discussed in LDM (2018-07-16)
- [ ] Decision in LDM
- [x] Rejected
- [ ] Spec'ed
Rocket science.
@asyncawaitmvvm
Sorry, but this comment is the drop in the bucket that gets you banned. As I told you a week ago, I don't like banning but in the end we want to focus on having a constructive discourse with the community. We can hide your comments, but they have become a distraction we don't need.
if( val != null &&= "some value"){ // do stuff } is this if statement a use case for the "assignment operators" feature?
Your sample looks like it's trying to do an equality check, not an assignment. It would not be part of assignment operators if it is not an assignment.
Here's an example of use - at least as far as I understand the proposal.
Since the right-hand side won't be evaluated once result is false, the Validate() function shown doesn't do any more work than necessary.
public class CreateProfileView
{
private string _userName;
private string _password;
private string _passwordConfirmation;
// ...
private bool Validate()
{
bool result = string.IsNullOrWhiteSpace(_userName);
result &&= string.IsNullOrWhiteSpace(_password);
result &&= string.IsNullOrWhiteSpace(_passwordConfirmation);
result &&= string.Equals( _password, _passwordConfirmation, StringComparison.Ordinal);
result &&= MeetsRulesForUserNames(_userName);
result &&= MeetsComplexityRequirements(_password);
result &&= UserNameIsAvailable(_userName); // Checks our database for active users
result &&= PasswordHasNotBeenPwned(_password); // Calls out to the API at haveibeenpwned.com
return result;
}
}
(Not that I'd actually write code like this - in the real world, we need actionable messages for the user, not just a simple true or false.)
@theunrepentantgeek I don't think that's a very good example since you could just use && in that case without any assignments. Where you cannot do that is if you're doing this in a for loop for example.
But on the other hand, if you're doing this in a loop, you should probably just exit early. Actually I'm not convinced this is a good feature at all :smile:
&&= would be useful for a loop that does constant-time equality checking to defeat timing attacks π
A very niche case, though.
An example of where I would have used this recently is with the visitor pattern:
class FooVisitor
{
public bool BarFlag { get; private set; }
public void VisitNode(Node node)
{
BarFlag ||= ExpensiveCheck(node);
}
}
I don't think that's a very good example since you could just use && in that case without any assignments.
@Neme12 You're absolutely right - I was just trying to illustrate the point for @codedek and anyone else who was curious. Though, I've written code like this in cases when I needed to single step in a debugger.
&&= would be useful for a loop that does constant-time equality checking to defeat timing attacks
Since I believe &&= would skip evaluation of the expression if the value is already false, I don't think you'd want to use if your code required constant type. You'd want to use &= instead.
To me the example from @jnm2 is the most compelling one so far.
@theunrepentantgeek oh yeah, duh. Whoops π
Sorry to bother, but could someone please help me understand what exactly this feature solves and why we need it? It seems like unnecessary complication to me, further steepening the learning curve of C#
@rakshith-ravi
Solves compound assignment of binary Boolean expressions. It doesn't complicate the language any more than any of the existing compound assignment operators, which happen to apply to almost every operator except && or || today. If anything, it makes the language more consistent with itself.
@HaloFour so correct me if I'm wrong, but will this:
var a &&= flag;
Roughly expand to this?
var a = a && flag;
Is that what it does? Is my understanding correct?
Minus the βvarβ.
LDM looked at this again today and we don't think this rises to the level of deserving a language change.
I should probably share that I've got a spec and a prototype for this feature, in hopes that this feature gets more traction and love
This could have been useful the other day in a bool property setter. It would have started with value &&= furtherConditions;. (Early return would not have been desirable.)
TL;DR question: Is this proposal dead in the water and permanently rejected, if so why?
This proposal was set to REJECTED on April 29, 2019, but I can find no mention of them in the LDM notes of any meeting of April 2019. The operators were discussed on July 16, 2018 as far as I can see, but the only thing mentioned in the notes was that they deserve their own proposal and should thus be splitted out from the ??= proposal.
@MadsTorgersen could you tell me/us why this proposal was rejected?
I started my own discussion (#6827) on this topic (because GitHub search had forsaken me). And was quickly pointed in this direction, and I can't gather from this issue (or the notes I looked through, maybe search is again failing me) why this proposal was rejected. The same was stated by @HaloFour in my short "discussion".
And while @333fred has removed the REJECTED label, as far as I can gather, it was just done so this issue is more easily searchable.
I'll leave the championed issue open so that it appears when people search, but I'm going to close this one.
Originally posted by @333fred in https://github.com/dotnet/csharplang/issues/397#issuecomment-655085109
So long story short... Why?
My recollection is that we rejected it because it just wasn't worth the effort. I was one pushing for it, and even I don't think it's that important.
I have no clue about the effort that goes into these things (just enormously grateful). And I do not wish to trivialize the effort, but to me (an relative outsider) the operator sounds like syntactic sugar over a = a || b;.
But isn't the fact that this issue was raised on at least 3 separate occasions here indicate that there is at least community support for these features? And why shouldn't it hold the same importance as other C# operators that we do have? I mean ??= is currently in the language, and would in my eyes hold the same importance (it was originally in the same proposal). Of all the boolean operators, those 2 are the only 2 that don't have a compound variant of it. I would thus also say that adding support for &&= and ||= would "complete" the language operator wise.
@CyrusNajmabadi
I was one pushing for it, and even I don't think it's that important.
Maybe worth reconsidering as a community contribution?
But isn't the fact that this issue was raised on at least 3 separate occasions here indicate that there is at least community support for these features?
Definitely. But that still may not be important enough to us. We have literal finate resources. So time spent on this is time not spent on other things. I think we collectively just said it was fast too low to be worth it.
@CyrusNajmabadi like @HaloFour stated, is it perhaps possible to consider this by way of community contribution? Because @Rekkonnect already said he had made a prototype:"
I should probably share that I've got a spec and a prototype for this feature, in hopes that this feature gets more traction and love
Possibly. I'll let @333fred weigh in. I know that community PRs are still very expensive for us. It helps with just one part of the costs here, but overall it's still something that will get likely push other work out.
Unless and until a member of the LDM decides to bring it for retriage, we won't accept pull requests for this feature.
To speak to how much work this feature would require, my ballpark is several hundred hours of engineering time. It's not quite the simplest language feature (that would probably be around 100 engineering hours), but it's also not that bad. It needs:
- Debate and approval by the ldm. This is ~14 people, meeting for at least an hour (likely several hours, especially when the implementation raises questions not considered in the original specification as it encounters edge cases).
- Implementation. For a feature like this, probably a week or two of work for a junior engineer. Less for someone very familiar with the area.
- Review. This is two roslyn developers, putting several hours of work to review the pr(s) implementing the feature. For a junior/external engineer, reviews are not a short process, and we often have to have significant chunks of the approach rewritten by the contributor during review.
- Min bar IDE work. At a minimum, the ide needs to behave ok in the face of the new feature before merge. A member of the IDE team needs to be a buddy on the feature to help with this (though the contributor is still doing most of the work) to ensure it meets the min bar.
- More IDE work. Min bar just means "it doesn't crash or make it hard to type". There still needs to be things like formatting options, refactorings, completion adjustments, etc.
- Test plan review. The compiler team meets (minimum 1 hour for the whole team) to go over the test plan and make sure there aren't any test gaps.
- Documentation. We work with our docs team to make sure there are basic docs available on the feature, with more complete docs soon to follow.
The list above isn't fully complete, but it's got a lot of it. As you can see, while an external contributor can help with some of it, we're still looking at a significant investment of compiler team time, even for a small feature like this one.
Jup... my previous point stands:
I have no clue about the effort that goes into these things (just enormously grateful).
Unless and until a member of the LDM decides to bring it for retriage, we won't accept pull requests for this feature.
Then my follow-up question would be: how do we get somebody of the LDM to retriage this? By gathering π emojis on this champion?
@synercoder Give them Something To Believe In by Poison. π€£
how do we get somebody of the LDM to retriage this
By giving us persuasive examples of how this would improve code enough to be worth the effort. Remember, I said several hundred engineering hours of work above. From my own experience, I've been annoyed at the lack of a &&= maybe 2 or 3 times in the past 6 years, and never been annoyed (that I can recall) at the lack of a ||=. I reach for ??= all the time. There is certainly the possibility that they'd come up more if I had the option available, but I somewhat doubt it. I just don't see many delayed &&s very often.