20 Apr 2015, 15:23

Type systems and narrative construction


What is a type system?

Mechanically, it defines what sorts of operations you can do on or data you can store in an “entity” (that entity could be a variable, an S-expression, a type itself, etc.).

But in reality, “can” is a really loose restriction. I own a sledgehammer and my program is running on a computer roughly two feet from me; in a very real sense I can null any type I want to (and probably many at once). Less drastically, Java lets me access private methods, alter final fields, etc. through the right invokations of the reflection APIs.

What type systems really do socially is give you standard tools to construct narratives. A narrative is a story about how you should use your code. It tells you “this knife is for cutting, not for prying (although you can technically do that with it if you absolutely need to and there are no other tools handy)”.

Instead of an implementor of an interface, you might say an object is an example of a trope. I metaphysically understand what connotations I am supposed to attach to, eg, a Man in Black entering through a smoky hallway as the horn section blares. In the same way, I metaphysically understand what is to be done with a Closeable in the package du jour when I am done with it. I further understand that, although there’s probably tons of private methods in there, I am only supposed to worry about one in particular, in the same way that I don’t worry about where the bathrooms are on the Millenium Falcon - it does not advance the narrative.

There are entire genres that allow more of reality to poke through and require what one might call “heightened suspension of disbelief”. Dogville is a good example - it’s obvious that it’s filmed on a soundstage where the buildings are “documented” by tape on the floor, but in no sense physically “enforced”. It leads to a certain aesthetic effect and a certain level of heightened audience participation in the same way that a complex library where all methods are public and their proper usage is lovingly detailed in comments has a certain effect on the way users contemplate it before actually importing anything.

The desirability of these aesthetic effects is mediated by the fact that code exists primarily to be used, not just read (although if it’s beautiful, so much the better). If all of your proper usage is documented, rather than enforced (even in an overridable way), you’re forced to actually read the documentation (there’s only four or so scopes in Java, but your documentation can say anything). In the context of a programmer’s day-to-day workflow, that actually disrupts the experience cultivated by using the “proper” subset of the code, and having that subset be immediately identifiable.

The Rails folks understand this quite well - people (like me, actually) complain about their “magic” but it lends itself to a certain cultivated experience (omakase). Their experience tends to derive from the operation of runtime hooks that extend behavior rather than compiler-enforced restrictions on behavior, but they have the same meta-level goal.

So as a language designer, the question you should ask is “what narrative building blocks do I want to provide?” It’s not about providing mechanisms for hiding functionality - it’s about letting your users tell clean stories.