null++ and its alternatives - NULL as an anti-pattern and some alternatives - stateless functional code
Notepad++ is a great and free text editor with many practical features, such as line-sorting, multi-file and directory find-and-replace, and excellent encoding support. However, programming is hard, and even the noble Notepad++ has been caught off guard in the war on bugs:
To NULL or not to NULL...
A display full of NULLs is not that desirable, but on the other hand is better than random, uninitialized data, or worse, reading beyond assigned buffers into memory regions containing data this user is not supposed to see.
The history of NULL is a controversial one: it was, somewhat like JavaScript, cheap to implement at the time and seemed a good idea. However, notoriously, even the inventor of NULL considers the invention to be a mistake.
At first glance, and when used in a very limited scope, NULL seems a sensible construct: a global kind of default 'this is not set' value, that is reliably detectable, as opposed to some random memory garbage. Issues arise when the NULL value (or worse, multiple values with multiple meanings) are passed around the various functions, objects and classes of a program. If component A passes a NULL to component B, then component B has the responsibility to check for NULL: if component B attempts to use the value without checking, then the behavior would be undefined (consider adding NULL to a piece of text, or to a number - what should the result be - another string or number, or another NULL?). Following the general principle of avoiding undefined behavior, then unchecked use of the NULL results in a NULL reference exception. And so, as NULLs propagate throughout the program, more and more checks must be made at each receiving point (the start of each function). This adds complexity to the program, and makes the program more fragile. More complexity also adds more cognitive load to the maintaining developer, who is then more likely to make mistakes...
Alternatives to NULL include:
- a wrapping type that encapsulates the concept of 'HasValue' and 'TheValue' - the Scala language has a built in type Option, which has been emulated in other languages such as C# as a best practice improvement over passing around NULLs.
- a suitable default value (Null Object pattern): for example if passing around an interface IPrinter, then if printing has been disabled, rather than passing NULL which requires checks on all usage points, instead pass a DummyPrinter object that is safe to use, and does nothing.
Somewhat related, and an even further step along similar lines of thought, is to minimize use of state, since state and side-effects of one function on another, add complexity to code and make it progressively harder to reason about, as the code base grows. Again, the Scala language takes such an approach, with the tension described by language designer Odersky as not so much Functional vs Object Oriented, but Stateless vs Statefull. In practice, for performance reasons many implementors find it necessary to at some point introduce state (for example, caching). However, the statefull code and be minimized. Following an immutable, functional approach can make code simpler and hopefully overall more robust, making it less likely to hit unexpected states that the poor end-user must deal with!
Comments
Post a Comment