The evolution of nothing

In the beginning, Brian and Dennis created C, and C had the void keyword, and Brian and Dennis saw that this is good. It all went downhill from there.

In C, void is not a data type, it is a keyword that denotes absence of return value or input parameters. Another usage of void in C is to declare pointers to untyped data, as in void*. C does not really have a special value representing “nothing”. The NULL pointer is a pointer like any other, usually defined along the lines of (void*)0L.

C++ pretty much inherited what C had, until C++11 defined nullptr value and nullptr_t type, which is a real data type. So, modern C++ has void keyword, nullptr value, and nullptr_t data type.

C# and Java have void keyword, and they have null value, but no special data type for that value.

Javascript does not have void, since it lacks type declarations in general, but to compensate, it has TWO empty values: null (no value) and undefined (like, really no value). This is a source of mild confusion, but can be ignored in most cases, e.g. something==null is true whether something is null or undefined.

Python has value None of type NoneType, and that’s pretty much it. Well, maybe that’s not so downhill.

Typescript outdoes them all. It has two empty values null and undefined, and 4 (four!) empty types: never (you ain’t gonna get a value), null (no value), undefined (like, really no value), and void (totally no value, I swear). There are also two language flavors: with strict null checks and without. never is a little like C’s void, one cannot declare a variable of type never. With strict null checks, undefined has one value undefined, void also has one value undefined, and null has one value null. Without strict null checks, all three can be either null or undefined. Oh yeah, and typeof null returns "object", in any mode, just for laughs (and for compatibility with Javascript, I guess). This is a lot ado about nothing…

PS. Did I mention you can combine types? The following happily compiles, even in strict null checks mode:

// Typescript
function f() : void | undefined | null | never {
   console.log("boo!");
}

f();

I suppose, proper implementation of this function that uses all four possibilities, would be

function f(): void | undefined | null | never {
   let random : number = Math.random();
   console.log(random);
   if (random < 0.25) return; // void
   if (random < 0.5) return undefined;
   if (random < 0.75) return null;
   while (true); // never return
}

Leave a Reply

Your email address will not be published. Required fields are marked *