Programmers often bemoan the problems of the concept of null that exists in programming languages. Even C.A.R. Hoare, the inventor of the null reference, calls it a billion dollar mistake. Some detest its existence, and indicate that it’s useless. However, it occurred to me that null can actually be thought of as a global variable - one that is used across all applications and domains to indicate special cases, such as the end of a data structure or a missing entry.
Null is a very useful concept across many fundamental data structures. Without null, a typical linked list implementation would need to define its own sentinel node reference to signify the end of a list. A typical tree implementation would need to define its own sentinel node reference to signify the absence of child nodes. A hash table would need to define a sentinel value to signify the absence of values in a particular bucket.
Application programmers would need to define their own domain-specific null references to represent the concept of “missing, but valid.” A database accessor that fails to find the record for a Person object in a human resources application would return its own sentinel Person object to indicate that the record could not be found, or be required to raise some sort of exception to its caller. Any programmer that maintains an object with optional fields would need to define their own sentinel value to indicate a missing field.
Rather than have each library or application declare its own custom sentinel representations, null is the convenient, global variable that gets (re)used everywhere to denote the special, non-exceptional, terminal case that signals to the programmer some special treatment may be needed, but is not required.