Documenting State with Types

The Problem

A large fraction of the flaws in software development are due to programmers not fully understanding all the possible states their code may execute in.

- John Carmack, In Depth: Functional Programming in C++

As apps get more complex, there's more states in disparate parts

Requiring more effort to understand

Or more opportunities for error

Rescale's Example

Building an API Client

Pass credentials to API Client methods


public interface MetadataClient {

  public CoreType getCoreType(long id, Credentials credentials);

  public Analysis getAnalysis(long id, Credentials credentials);

  ...
}
            

We make many requests for the same job (same credentials)

Pain to pass around creds or recreate

Prevents developers from using the client as much as we'd like

Let's use state!

Just set the credentials at the start


// at start of message processing
metadataClient.setCredentials();
// ... do work
metadataClient.clearCredentials();
            

Started using our metadata client in other contexts

Always forgot to set credentials

Subtle assumptions led to brittle classes

State is useful...

but needs to be obvious

indicate the state with a type

Java's declarative static typing will always remind us


public class AuthenticatedClient {
  private final MetadataClient client;
  private final Credentials credentials;

  public AuthenticatedClient(MetadataClient client,
                             Credentials credentials) {
    this.client = client;
    this.credentials = credentials;
  }

  public Analysis getAnalysis(long id) {
      return this.client.getAnalysis(id, this.credentials);
  }
...
}
            

Obvious when client is authenticated or not

Prevents a whole class of errors

Even deeper than "Let the compiler catch it"

The type system is a tool

github
@akud
email
adkudlick (at) gmail (dot) com
slides
akud.github.io/types-indicating-state