There are two parts to this response. Firstly, let's talk about adding types to the spec.
I'm trying to have my cake and eat it too: to keep Teleport minimal but to encourage extensibility. We both know the trade-offs involved in adding functionality and in the case of Teleport, I lean heavily towards minimalism (which IMO is a big contributing factor to the success of JSON). Because of this, I emphasize that type-checking existing JSON documents is *not* a design goal of Teleport (for that purpose, there is
http://json-schema.org/). Instead, Teleport provides a minimal set of building blocks, which should *not* include null. The inconsistency created by null greatly outweighs its legitimate use cases, which are few. I explain this in the second part of the email.
Having said that, an extended version of Teleport that *does* make type-checking existing documents its goal would be quite useful, despite stepping into JSON Schema's territory. For this project, Nullable is an excellent type: elegant and composable that covers just about every real-world use of null in JSON. If a type is useful but not fundamental enough to be in the spec, where should it be defined? This is an open question, and an important one for Teleport as a project.
The formal definition for Nullable can be written as simply as this:
x :: t({"Nullable": p}) if and only if x = null or x :: t(p)
Now I explain my decision against null.
First of all, there are two distinct concepts of null:
1. In static type systems (SQL, Java etc.), null represents the absence of a value. It is the Nothing in Haskell's Maybe.
2. In dynamic type systems, null is a singleton value which is used as a placeholder for a missing value.
I don't have a problem with either of these definitions, but I have a problem with the way #2 is usually implemented, including in JSON. The dynamic null is great, but its semantics are weakened by the fact that most dynamic languages provide *multiple* ways to represent missing data. Python has None, but it also has IndexError, KeyError, AttributeError etc. JavaScript has null, but it also has undefined [1].
In JSON (a dynamic type system), you have, broadly speaking, three ways to represent missing data:
a. By putting null in place of a value (at document root [2], in arrays, in objects)
b. By omitting the value along with its name (in objects)
c. By omitting the entire document [3]
For document root and objects respectively, (b) and (c) are obviously preferable [4]. As such, we are left with just one justifiable place for null: JSON arrays. I can think of two use cases for null array elements: naive sparse arrays and tuples, and I don't think either of them deserves to be in the Teleport core. Sparse arrays are obscure and tuples (w/ Nullable) are functionally equivalent to Structs, so adding Tuple into the core will force people to make a choice between Tuple and Struct whenever they need to group some values. This is a completely inconsequential design decision that can be made once and never bothered with again.
Overall, the justifiable use cases for null are so rare that I'm convinced that including it in JSON in the first place was a mistake. Frankly, I would like to force null out of Teleport entirely by making Teleport operate on a null-less subset of JSON, but this would break the wildcard type and the ability to make an extension of Teleport as described in the first part of the email, so I'm keeping it.
[1] I'm not sure what undefined really is, but it behaves like a singleton value, same as null
[2] Not allowed by the JSON spec, probably as a result of a similar discussion
[3] For example, an HTTP response with an empty body where a JSON body was expected
[4] In some cases, there are two semantically distinct ways that a value can be missing in an object. In these cases using (a) and (b) to distinguish between them may be an elegant approach. IMHO, for every legitimate use case there will be dozens of ill-conceived ones. I think most people working with JSON have encountered errors or were forced to write defensive code as a result of this.