Collected · Redux · MIT

Temporary exhibition · Hall of the Commons

Thirty Signatures for Fifteen Lines

TypeScript·2015·61 lines·1563 bytes

Curator’s note

Sixty-one lines, of which the working code is the last fifteen. Everything above it is the type system being asked for something it cannot give.

What compose does is one line: take functions and nest them, so that compose(f, g, h) behaves as (...args) => f(g(h(...args))). The implementation is a single reduce, and it would be the same single reduce in any language with first-class functions. It is the plainest possible expression of an idea that has been in mathematics since long before there were computers.

Now count the declarations above it. There is one for no arguments, one for a single function, one for two, one for three, one for four, and then a catch-all — because TypeScript cannot express "a list of functions where each one's output type is the next one's input type" for a list of unknown length. That is a statement about the type system rather than about Redux. The constraint is real, other type systems can express it, and the ones that can pay for it elsewhere.

So the overloads are not clumsiness. They are somebody deciding that four composed functions is as far as anyone reasonably goes, writing the exact types for those cases, and falling back to any past it. The final signature returns (...args: any[]) => R, which is the file admitting where the guarantee stops.

It hangs beside createStore from the same project because the pair says something neither says alone. One is a hundred lines of runtime doing real work. The other is fifteen lines of runtime carrying forty-five lines of apology to the compiler, and both shipped in the same library on the same day.

Elsewhere in the museum