dealing with nulls and zero #2532
-
There seems to be a problem with how this language deals with nulls and zeros. Now that I have outlined the theory of zero, why is it relevant?
Obviously, if there is valid data for Employee.Name, the statement should be false. I would like to get feedback on what other problems this theory might address. |
Beta Was this translation helpful? Give feedback.
Replies: 41 comments
-
The meaning of null, zero, empty string, etc. are all highly dependent on the context. As such unlike C++ and JS, C# requires you to be explicit about how you want to treat them. Given the sheer scale of the disaster type coercion is in JS this is definitely the right decision. Consider the fact that the |
Beta Was this translation helpful? Give feedback.
-
Would there be a way to indicate that you want it to act this way, but have it act normally otherwise? |
Beta Was this translation helpful? Give feedback.
-
Yes if(string.IsNullOrEmpty(Employee?.Name)) |
Beta Was this translation helpful? Give feedback.
-
You say that the definitions of null, zero, empty strings are highly dependent on the context, It seems to me that people should "sit down" and figure out exactly what they should mean so that there can be some sort of standard. Having things like that being "highly dependent on the context" is unacceptable. It basically means that we have no idea what it means except by how it happens to be used. |
Beta Was this translation helpful? Give feedback.
-
We know exactly what an empty string means. It means that a string contains no characters. What's highly dependent on context is what you do with an empty string. |
Beta Was this translation helpful? Give feedback.
-
Then we need to figure out how they should be used. |
Beta Was this translation helpful? Give feedback.
-
They will be used differently depending on your application, and what the string represents. |
Beta Was this translation helpful? Give feedback.
-
A string can represent a name, a collection of characters, a piece of text, a byte array etc. All of these cases will need to deal with empty strings differently. An int can represent an age, the number of items in a collection, an Id, an offset, a port, or a thousand other things. Every single one of those scenarios treats 0 differently. |
Beta Was this translation helpful? Give feedback.
-
And yet zero should mean the same thing in almost every case. In almost every case it should be what the value is initialized to and it should mean that there is no valid data. |
Beta Was this translation helpful? Give feedback.
-
One can always say things depend on the situation, but there is value in finding commonalities and underlying patterns. |
Beta Was this translation helpful? Give feedback.
-
Is 0 a valid age? Is 0 a valid network port? Is 0 a valid price? Is 0 a valid weight? The answer to every single one of those questions is different: Yes. |
Beta Was this translation helpful? Give feedback.
-
I'm gonna re-post something I put in another GitHub Issue here:
Because, if it does, it will hit the first page of memory, which is reserved by the operating system, and trigger a page fault. In the CLR, this becomes a When it comes to most data structures,
If we have a field for paint cans, an empty array or empty Enumerable should represent that we do not carry paint cans. If it's a field for a singular paint can, then null could be indicative of no paint can, and this is it's generally accepted use. This does not mean zero.
So if we have none, it could be zero, or it could be null, and if it's null then there are zero, but if there are zero it might not be null? Using two different values interchangeably to mean the same thing is a 'fun' vector for bugs.
This sounds like you need an enum. There is no current type in the BCL that can reflect these four states. This also reminds me of the tri-state bool.
So what are negative numbers then, if we've already used "zero" for invalid and "true" for valid? Assigning roles like this may make sense in some limited domains, but this isn't something you can generalize to the language level.
"null strings" are not a thing. A lot of the standard library treats
All variables are initialized to zero by default, and for reference types, that's a zero pointer, also known as |
Beta Was this translation helpful? Give feedback.
-
That C# makes you very explicitly deal with the differences in data types is not a problem. It is very intentional and based on the fact that languages that permit such implicit coercion and "truthiness" are loaded with bug vectors.
|
Beta Was this translation helpful? Give feedback.
-
Maybe the solution would be to allow a ~= operator that could make such coercion possible without sacrificing the type strictness of the nominal case. |
Beta Was this translation helpful? Give feedback.
-
As others have said, what you are proposing leads to some of the worst bugs in JavaScript, leading to many to ban the use of |
Beta Was this translation helpful? Give feedback.
-
We already have that concept. We can compare a variable to |
Beta Was this translation helpful? Give feedback.
-
How do you define what is meaningful? As i showed above it's domain specific. For some domains a string isn't meaningful if it's full of whitespace, in others it would be.
Not really no. I recommend you try as it might be very informative. |
Beta Was this translation helpful? Give feedback.
-
We do not have that concept. Remember, null, 0 and "" are different and distinct concepts. I disagree, the language does need such a concept and badly because if we don't have this concept, we end up compartmentalizing everything and we end up not being able to generalize to a higher level. By not being able to generalize to higher level concepts, we end up being stuck at a lower level of detail. One of the main problems with computing is having to do everything at a low level of detail and not being able to handle higher level abstractions. This slows down software development. |
Beta Was this translation helpful? Give feedback.
-
Yes, they are, and they should be. If you want to treat them as equivalent, write a function to do so.
I disagree. Generalizing this concept and across data types is one of the leading causes of bugs in the languages that allow it. C# made the decision to not treat If you want this generalization, write your own function.
I'll take slightly slower software development resulting from having to explicitly consider my data types over chasing down the inevitable flood of bugs any day of the week. |
Beta Was this translation helpful? Give feedback.
-
How do I define what is meaningful? It seems like it is domain specific, but it could be generalized possibly with some user preferences. White space is meaningful in general, but there could always be a preference or option to change this for a particular user or circumstance. Just because there are problems with the concept doesn't mean that it couldn't be done - if we allow it to be flexible. |
Beta Was this translation helpful? Give feedback.
-
Remember, C# 8 is doing a lot to deal with the null problem - it's moving
towards getting rid of them! The last thing we need is a new feature that
makes them more prevalent again...
…On Thu, 16 May 2019 at 21:35, HaloFour ***@***.***> wrote:
Remember, null, 0 and "" are different and distinct concepts.
Yes, they are, and they should be.
If you want to treat them as equivalent, write a function to do so.
I disagree, the language does need such a concept and badly because if we
don't have this concept, we end up compartmentalizing everything and we end
up not being able to generalize to a higher level.
I disagree. Generalizing this concept and across data types is one of the
leading causes of bugs in the languages that allow it. C# made the decision
to not treat null like 0 like false specifically because of learning from
the bad experiences from C and C++. Truthy/Falsy is a constant source of
bugs in JavaScript.
If you want this generalization, write your own function.
This slows down software development.
I'll take slightly slower software development resulting from having to
explicitly consider my data types over chasing down the inevitable flood of
bugs any day of the week.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<https://github.com/dotnet/csharplang/issues/2532?email_source=notifications&email_token=ADIEDQKMS7LNGW7SIV3UDZLPVXAQPA5CNFSM4HNKIUCKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODVS7SXA#issuecomment-493222236>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ADIEDQOCNCYAZ7M6TXWGW5DPVXAQPANCNFSM4HNKIUCA>
.
|
Beta Was this translation helpful? Give feedback.
-
What is your concept? Please explain it fully. You have also avoided the points i've made. Such as the fact that whether or not data is meaningful is unrelated to whether or not it is null, empty or 0. For example, the empty string is very meaningful in many domains. But it's completely non-meaningful in others. How do you create your concept such that it deals with this fact? |
Beta Was this translation helpful? Give feedback.
-
Yes. We have a way to specify that preference. But using functions like etc. etc. etc. How are you actually going to provide a way for people to specify hte infinite number of meanings of what is "meaningful" or not? |
Beta Was this translation helpful? Give feedback.
-
I will try to clarify what I meant be meaningful data. |
Beta Was this translation helpful? Give feedback.
-
But empty strings are very meaningful in many domains.
boolean types only have
Why is zero not meaningful? What about all the domains where 0 is a perfectly expected and natural value? -- Regardless, here's your solution: public static bool IsMeaningful(this object o)
{
switch (o)
{
case string s: return s.Length > 0;
case bool b: return b;
case null: return false;
case Array arr: return arr.OfType<object>().Any(a => a.IsMeaningful());
default:
try { return Convert.ToInt64(o) != 0; } catch { }
try { return Convert.ToUInt64(o) != 0; } catch { }
return false;
};
} You don't need a language helper for this. You can just define your helper and put it on nuget and people can use it if they want. |
Beta Was this translation helpful? Give feedback.
-
Here's teh crux of the problem: "the way we would want" is person, team, group and domain dependent. I absolutely do think of empty strings as meaningful in my domains. 0 is also meaningful. Arrays have no concept of meaningfulness for me whatsoever. etc. etc. You keep saying this as if there's consensus in the c# ecosystem about this, but there isn't. And there's broad belief that languages that have done similar things (i.e. JavaScript) screwed up here as this is not a good concept to have in the language. C# very intentionally and explicitly has not done this because it's actively felt to be a bad enough idea by enough of the LDM and enough of the community. |
Beta Was this translation helpful? Give feedback.
-
It is a shame no one can come to a consensus. I believe the idea is good, but obviously the people that have tried similar things like JavaScript have failed to get it right and have spoiled people's opinion of trying such things. Obviously you are right "the way we want" is person, team, group and domain dependent, but there is also common threads or ideas that could make for a new concept or standard if people were open to it. Thanks everyone for listening to this failed idea because it has helped me to understand the problems we face. |
Beta Was this translation helpful? Give feedback.
-
Good luck with your journey! As i mentioned above @llfletch: i highly recommend you actually try this out and create a library you think woudl be valuable here. You can even host that library on nuget, and if it's positively viewed by the community, will get used in more and more places. If it turns out that you, along with the community, can form a good set of rules here, it's possible in the future that thoughts on this might be different. |
Beta Was this translation helpful? Give feedback.
-
That is exactly what I plan to do. Thank you.
Sent from my Verizon, Samsung Galaxy smartphone
…-------- Original message --------
From: CyrusNajmabadi <[email protected]>
Date: 5/16/19 5:14 PM (GMT-07:00)
To: dotnet/csharplang <[email protected]>
Cc: llfletch <[email protected]>, Mention <[email protected]>
Subject: Re: [dotnet/csharplang] dealing with nulls and zero (#2532)
Good luck with your journey! As i mentioned above @llfletch<https://github.com/llfletch>: i highly recommend you actually try this out and create a library you think woudl be valuable here. You can even host that library on nuget, and if it's positively viewed by the community, will get used in more and more places. If it turns out that you, along with the community, can form a good set of rules here, it's possible in the future that thoughts on this might be different.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub<https://github.com/dotnet/csharplang/issues/2532?email_source=notifications&email_token=AJFPOKGKDMEQMSVPZXQVXGDPVX2H7A5CNFSM4HNKIUCKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODVTMBTY#issuecomment-493273295>, or mute the thread<https://github.com/notifications/unsubscribe-auth/AJFPOKGAPUGMQOGE6TGF6FTPVX2H7ANCNFSM4HNKIUCA>.
|
Beta Was this translation helpful? Give feedback.
-
You have a goal of trying to define a common set of principles around equivalence between different values. But that is not possible as there is no common set of principles. There literally can't be because domains vary so much. And there's no better example of this than the exit status from commands in Linux. Zero means success. Non-zero means there was an error. This even embodied in two bash commands, Zero absolutely is meaningful, sometimes. And that's the problem: for any rule you invent, sometimes that rule will be plain wrong for a given domain. |
Beta Was this translation helpful? Give feedback.
The meaning of null, zero, empty string, etc. are all highly dependent on the context.
As such unlike C++ and JS, C# requires you to be explicit about how you want to treat them.
Given the sheer scale of the disaster type coercion is in JS this is definitely the right decision. Consider the fact that the
==
operator is now essentially banned from many JS codebases, and all usages are replaced with===
which has a much stricter definition of equality.