-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
&&= and ||= #397
Comments
What behavior do you want for the operators &&= and ||= ? |
@TonyValenti what's wrong with var ret = TryMethod1()
|| TryMethod2()
|| TryMethod3(); ? And of course you know, && and || are lazy operators and they halt when result cannot be changed due to absorption with true/false constant. You can write var ret = false;
ret |= TryMethod1();
ret |= TryMethod2();
ret |= TryMethod3(); It's completely valid in C#. But your proposition just doesn't make sense. |
@AdrienTorris it's not, if any of the previous method returns true, I assume that |
|
@drewnoakes I might expect that from something like ??= but not &&= or ||= |
Derp. You're right. That's what commenting from a sofa looks like :) I was wondering about ??= the other day, then saw this. Brian conflated the two. |
+1 for ??=
On Sat, Apr 1, 2017 at 8:52 AM Drew Noakes ***@***.***> wrote:
Derp. You're right. That's what commenting from a sofa looks like :)
I was wondering about ??= the other day, then saw this. Brian conflated
the two.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#397 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AM-qVrdhfhc1UN-0KvT7DcUIzIAldD5Kks5rrlaXgaJpZM4MwdeE>
.
--
Tony Valenti
|
|
I would be willing to champion this. But i haven't had time to work on my other championed features yet :-/ |
Existing issue #34 tracks support for null-coalescing assignments via |
I'm confused by this request (especially by the suggestion that @CyrusNajmabadi would consider championing it), as I don't see how it would achieve anything that isn't already offered by the language. As @Pzixel points out, the OP can achieve the requested functionality in his example, using: var ret = false;
ret |= TryMethod1();
ret |= TryMethod2();
ret |= TryMethod3(); So what would the |
It wouldn't always evaluate the right-hand side. |
Ah, I get you. Again as @Pzixel suggested, this can already be achieved via: var ret = TryMethod1()
|| TryMethod2()
|| TryMethod3(); And if the two tests need to occur with some other statement between them, then the two results have different meanings, so should have different variable names: var result1 = TryMethod1();
DoSomething();
var result2 = result1 || TryMethod2(); But I know some folk like to overload their variables with multiple meanings, so I can see why |
I agree that it can already but achieved, however I also see some value in breaking the intermediate result out into a variable. This allows for easier debugging, and naming of the variable can aid in readability and intrinsic documentation. |
Indeed, which is why it's a good idea to avoid using |
@DavidArno This works especially well with if statements. I treat mutable variables like this as builders. The meaning doesn't change during construction. |
&&= and ||= are good for general accumulation-style algorithms (just like += and the like). ??= is good for algorithms that want to lazy initialize something only when necessary. i.e.: // making a connection is expensive and should be deferred until necessary. once made, the
// same connection should be used from that point on.
SqlConnection connection = null;
foreach (var blah in whatever)
{
// lots of logic
...
if (yupINeedConnection)
{
connection = connection == null ? new SqlConnection() : connection; // or
connection = connection ?? new SqlConnection();
// use connection.
...
}
} This is more nicely written as: // making a connection is expensive and should be deferred until necessary. once made, the
// same connection should be used from that point on.
SqlConnection connection = null;
foreach (var blah in whatever)
{
// lots of logic
...
if (yupINeedConnection)
{
connection ??= new SqlConnection();
// use connection.
...
}
} &&= and ||= are generally useful while looping, and while you need to process every element, but where you want to accumulate some final boolean value. For example: var runAgain = null;
foreach (var token in this.DescendentTokens())
{
// do a lot of stuff.
runAgain = runAgain || ComputeSomethingExpensive(something);
} This is nicer as: var runAgain = null;
foreach (var token in this.DescendentTokens())
{
// do a lot of stuff.
runAgain ||= ComputeSomethingExpensive(something);
} Basically, the operators just simplify general lazy/accumulation patterns that do show up elsewhere. Is this super important? Definitely not. But it's nice and consistent, and likely easy to slot in. Basically, any time the language has an operator that you could do: "x = x op y", then it would be nice to have a "x op= y" version for uniformity. |
I can't find it at the moment but I recall |
@CyrusNajmabadi With the loop, wouldn't you prefer to |
@jnm2 Only if the goal was to determine if we needed to set "runAgain". But often you may still have other work you need to do with the rest of the items in your collection. Hence the " // do a lot of stuff." line. The implication here is that it's important that we process all the items. But that we only want to ComputeSomethingExpensive as long as it is returning false. once it returns 'true' once, we don't need to again. |
Your example highlights different styles of programming creating different syntax needs. Your example: foreach (var token in this.DescendentTokens())
{
// do a lot of stuff.
runAgain ||= ComputeSomethingExpensive(something);
} would end up something like the following in my hands: foreach (var token in this.DescendentTokens())
{
DoALotOfStuffWithToken(token);
if (expensiveComputationProvider.RunAgain)
{
...
}
} I'd expect the state of whether However, I like the idea of bool RunAgain => (_expensiveComputationResult ??= ComputeSomethingExpensive()).RunAgain; And if But seriously, could we please complete pattern matching and add |
@DavidArno this little nice to have stuff could probably be done by the community, if the LDT ever decides to relax their iron grip on the development reins. |
Managing algorithmic state is totally fine for a function to do IMO :) I mean, do you not accumulate values in your functions ever? Do you never use ++ anywhere? After all, you could take that incremented local state and put it in some other "computation-provider" struct/class. Regardless, people have state in functions today. All the time. I see nothing wrong with making working with that state more pleasant. --
There is no way that i'll be able to champion any of those things to hte language. I do not have the time, and i'm completely booked on working in the IDE space and on things like IOperation. But, i can potentially squeeze in time for language features that i think just make things more pleasant at low cost. Hence why i'd be willing to champion it. If i don't champion it, it just means that it doesn't get done. It doesn't mean those other things get done. |
@orthoxerox At the end of the day, the LDM is going to decide what does/doesn't go into the language. Just consider how many proposals are out there. Consider how many of them you probably don't like :) Now consider what sort of language you have if there isn't something preventing all those language changes from just getting added to the language whenever someone in the community wants it. :) |
I'd be lying if I said I never used such features. But it is incredibly rare that I do. Different approaches... |
Exhibit A: out/is var and scope leakage. Near-universally disliked by the community, but we got it anyway. Clearly the LDM team doesn't protect us from features we don't like... |
GitHub is not a large percentage of the entire community from what I gather. |
Ah yes, I forgot that significant part of the "community" that communicate with the LDM in secret... 😆 |
@DavidArno Who says the communication is secret? |
@DavidArno Yes, you forgot about enterprise customers that ask for features through their account managers. |
That communication takes place (such communications were used as a major argument for out var scope leakage, for example), yet they aren't public. So they are secret. And that, I feel, is the real reason behind the LDT keeps a vice-like grip on new features. Those enterprise customers would be less than happy if they suddenly had to argue their case with the community. |
This feature request is already an open question as part of an existing championed proposal, which has been triaged by the LDM for possible inclusion in some minor or major release. |
@gafter, I may be mistaken but I think this issue differs. It's referring to logical |
@drewnoakes It's
|
@GeirGrusom, they're similar, but not the same. There's a separate issue tracking |
How does this issue differ really? The difference between |
@gafter wrote:
@drewnoakes wrote
Quoting from https://github.com/dotnet/csharplang/blob/master/proposals/null-coalecing-assignment.md :
Does that look different to you? |
@gafter perhaps you should close this as a duplicate in that case. |
@drewnoakes This is a discussion issue. The other is a tracking issue for a related championed proposal that may come to include this feature. I don't expect we'll be closing discussion issues. |
Wow it's been a hot minute since this has been brought up again but seeing as the null coaelescing operator proposal is pretty much done without these operators included, will this proposal ever be brought back up in an LDM or will it continue to live inconclusively ever after? |
It may be brought up in the future if any LDM members wishes to champion it. |
It was championed, and explicitly rejected by LDM: #1718 |
Gotcha, should these issues be closed then to prevent further confusion?
…On Tue, 7 Jul 2020 at 20:41, Fred Silberberg ***@***.***> wrote:
It was championed, and explicitly rejected by LDM: #1718
<#1718>
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#397 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACVEYI4HXLZ4WK3O3ZKZEMDR2N27NANCNFSM4DGB26CA>
.
|
I'll leave the championed issue open so that it appears when people search, but I'm going to close this one. |
Note that the description of the champion issue doesn’t currently specify
that the proposal is rejected, and may not see the small comment that
specifies that it is rejected.
…On Tue, 7 Jul 2020 at 20:43, Fred Silberberg ***@***.***> wrote:
Closed #397 <#397>.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#397 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACVEYI6J3WGS772Z25WUZLTR2N3G3ANCNFSM4DGB26CA>
.
|
__result is a bool coming in by ref that needs to be changed but also consider its original value in the end value.. we ended up having to write this: __result = __result && SomeMethod(); Would have been nice to write: __result &&= SomeMethod(); I realize this is niche, but it.. is a legitimate use case! Heh. |
Hi All,
I would like to request that C# add &&= and ||= operators so I can write code as follows:
The text was updated successfully, but these errors were encountered: