Constraints liberate, TypeScript edition

A little TypeScript puzzle I encountered recently:

interface Valid {
  readonly isValid: true;
}

interface Invalid {
  readonly isValid: false;
  message: string;
}

type Validation = Valid | Invalid;

function report(validation: Validation) {
  if (!validation.isValid) {
    console.error("Invalid", validation.message);
  }

  console.info("Valid");
}

Looks fine right? And the TypeScript playground has no problem with it. But in my local environment, it was complaining that the message property didn’t exist on validation, despite the fact that validation should be narrowed to Invalid in the if branch.

Typesafe builders with GADTs

I wrote something a while back about typesafe builders (builders which let you add information in any order you like, but fail to compile if you try and build the result without having added all the required information). The implementation was in Java, so I used subtyping to represent types that do include information, don’t include information, or are indifferent to whether they include information. But I’ve been wondering, how would you implement this in a language without subtyping? It turns out one answer is generalised abstract data types (GADTs).

If there's a concern, it's your concern

Aspect-oriented programming is still a fairly popular programming tool. The idea is to reduce the coupling, and increase the modularity, of programs by providing “aspects” to handle “cross-cutting concerns” separately, rather than intermingling these concerns with each other and with a program’s specific business logic. The problem with this approach is that cross-cutting concerns, in the way required by aspect-oriented programming, are vanishingly rare.

Functional programming is infectious

You learn about clever purely-functional abstractions and you think, neat, but not really relevant to everyday programming; then the next thing you know, you’re implementing a fairly boring bit of business logic and you think, dammit, what I really need here are profunctor optics.

Mainstream programming languages now generally include some support for functional idioms: first-class functions, map, maybe fold. The idea seems to be to introduce functional features to be used when they are convenient, but to avoid the more complicated functional abstractions. This usually turns out to mean writing functional code mostly at a small scale.

Dependency injections frameworks are pure ideology

Mingus believes now that it got too far away from jazz – spontaneity – since almost all of the music was written. He remembers one rehearsal at which Teddy had left several bars open for blowing and everyone jumped on him with ‘Man, are you lazy? Write it out!’

Dependency injection is a great idea. Supplying dependencies to a class, rather than having the class create them themselves, is a practical illustration of the benefits of the single-responsibility principle. Creating dependencies is a different responsibility from using them, and the class that uses dependencies probably doesn’t (or shouldn’t) have the information required to create the dependencies; so you can isolate this responsibility by in a separate class (or multiple classes, for different environments or for testing) by injecting the dependencies. But dependency injection doesn’t require a framework, and indeed dependency injection frameworks are useless if they’re not actively harmful; their continued prevelance is the zombie-like persistence of a dead ideology.