Jezen Thomas

Jezen Thomas

CTO & Co-Founder at Supercede.

Rich Hickey Doesn't Know Types

Clojure inventor Rich Hickey argues in one of his talks that:

a -> a; [a] -> [a]; It means nothing! It tells you nothing!

— Rich Hickey, Effective Programs.

If we take him to mean “a -> a”, this is actually one of the simplest ways to understand parametricity.

At first glance, it looks like a function of type a -> a could do anything. But parametricity rules that out. If you pass in a 1, it can’t return 2 — because the function must also work for any other type, not just numbers. There’s no general “+1” operation across all types. Likewise, concatenation only works for types with the right structure. In fact, the only lawful implementation is the identity function:

id :: a -> a
id x = x

The signature also tells us there are no effects involved: there’s no IO present, so the function can’t read from or write to the outside world.

Now consider [a] -> [a]. Yes, technically there are infinitely many implementations (a, a ++ a, a ++ a ++ a, …), but they’re still highly constrained. You can reverse a list, drop elements, take elements — but you cannot inspect or manufacture new a values. Parametricity tells us a great deal.

A true shuffle would need a source of randomness, e.g.:

f :: Seed -> [a] -> [a] -- pass a seed
-- or
f :: [a] -> IO [a]      -- obtain randomness in IO

This is the opposite of “nothing”: the signatures rule out far more than they permit, and those exclusions are exactly what make them informative.

As Kris Jenkins put it in Communicating in Types:

When you have a type error — and you always get a type error — the question is whether you get it from QA, or your users, or your compiler.

Type systems like Haskell’s aren’t a panacea, and there are some things that a language with a dynamic type system can do that are harder to achieve in Haskell (though what this means in the context of a business is a separate discussion). But dismissing these general types as uninformative overlooks the guarantees parametricity provides.