Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't the C# compiler throw for logical comparisons of null?

Tags:

c#

logic

I was eating lunch with a friend yesterday and they were complaining about null in C#. He stated that null was illogical. I decided to test his claims, so I tested some simple logical propositions:

Console.WriteLine(null == null); //True
//Console.WriteLine(null == !!null); //BOOM

Console.WriteLine(10 >= null); //False
Console.WriteLine(10 <= null); //False

Console.WriteLine(!(10 >= null)); //True
Console.WriteLine(!(10 <= null)); //True

Checking equality seems straightforward and this is what I would expect. The greater/less than statements however are logical contradictions which I find really confusing! Shouldn't these throw? The negation operation throws as you would expect.

If I try to run comparisons (aside from equality) using null in Ruby or Python I get a type error along the lines of "cannot compare a number to nil". Why doesn't C# do this?

like image 308
Pookchop Avatar asked Apr 03 '18 18:04

Pookchop


People also ask

Why is there no string in C?

Both Java and Python have the concept of a "string", C does not have the concept of a "string". C has character arrays which can come in "read only" or manipulatable. A character array is a sequence of contiguous characters with a unique sentinel character at the end (normally a NULL terminator '\0' ).

Why is C not A or B?

Because C comes after B The reason why the language was named “C” by its creator was that it came after B language. Back then, Bell Labs already had a programming language called “B” at their disposal.

Why C has no exception handling?

As such, C programming does not provide direct support for error handling but being a system programming language, it provides you access at lower level in the form of return values. Most of the C or even Unix function calls return -1 or NULL in case of any error and set an error code errno.

Why there is no namespace in C?

Namespace is a feature added in C++ and is not present in C. A namespace is a declarative region that provides a scope to the identifiers (names of functions, variables or other user-defined data types) inside it. Multiple namespace blocks with the same name are allowed.


1 Answers

Excellent question.

Try not to think of null as a specific value but rather "nothing to see here." The documentation defines null as

The null keyword is a literal that represents a null reference, one that does not refer to any object.

With that in mind, the fact that null is not an object means that the classical laws of thought don't exactly apply to it (or, at least, don't apply to it in the same way that it would apply to an actual object).

That being said, the fact that 10 >= null and 10 <= null are both false isn't, strictly speaking, a contradiction - after all, null is quite literally nothing. If you said 10 >= (some actual thing) and 10 <= (some actual thing) were both false, then clearly that would be contradictory, but you can't exactly have a contradiction in the classical sense without some actual object. Aristotle's definition of the law from Metaphysics is as follows:

It is impossible that the same thing can at the same time both belong and not belong to the same object and in the same respect, and all other specifications that might be made, let them be added to meet local objections...

So, we have a bit of a "loophole" here in a sense. At least as Aristotle formulated the Law of Non-Contradiction, it was referring specifically to objects. There are, of course, multiple interpretations of the Law of Non-Contradiction at this point.

Now, turning to the case of 10 + null. We could say that this is the same thing as null + 10 if it's easier. In a sense, then, what should happen at this point - should null "swallow up" the 10, or should we just say "10 + (nothing at all) really should just equal 10"? Truthfully, I don't have a very convincing answer here from a logical perspective beyond saying "well, that's kind of a design choice." I suspect that the language designers wanted to distinguish 10 + null from 10 + 0, but I don't have documentation to prove that. (Indeed, it would be slightly strange if they were the same; after all, 0 is an actual value that can be constructed from the natural numbers, but null is "no value whatever").

like image 174
EJoshuaS - Stand with Ukraine Avatar answered Sep 20 '22 15:09

EJoshuaS - Stand with Ukraine