Title Text

Algebraic data types

data what ?

data

types

Algebraic

What are types used for?

Optimisation !

Fewer bugs

  • No !
  • but yes...
  • but no...

Complex

  • No !
  • it's just a shift in complexity towards the build part

Types can simplify your code !!!

Accidental complexity

Optionality

Null pointer

let person = {
    name: "Alice",
    age: 30,
    address: null
};

Null pointer

interface Person {
    id: number;
    name: string;
    age: number;
}

function findPersonById(people: Person[], id: number): Person | undefined {
    for (const person of people) {
        if (person.id === id) {
            return person;
        }
    }
    return undefined;
}

Charles Antony Richard Hoare

I call it my billion-dollar mistake. It was the invention of the null reference in 1965. At that time, I was designing the first comprehensive type system for references in an object oriented language (ALGOL W). My goal was to ensure that all use of references should be absolutely safe, with checking performed automatically by the compiler. But I couldn't resist the temptation to put in a null reference, simply because it was so easy to implement. This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years.

Option type

Option type

type option('value) =
  | None
  | Some('value);

Schrodinger's cat experiment

Type option in action

Type option in action

Success

function divide(a: number, b: number): number

Signatures can lie !

Type result

type result('a, 'e) = 
  | Ok('a)
  | Error('e);

Type result in action

Always favor the result type as much as possible over exceptions

please make your function signatures explicit

let divide = (a: number, b: number): result(string, int);

let divide_exc = (a: number, b: number): number;
@type result :: {:ok, integer()} | {:error, string()}

@spec divide(integer(), integer()) :: result
def divide(a, b) do
  try do
    result = divide!(a, b)
    {:ok, result}
  rescue
  	e in RuntimeError -> {:error, e}
  end
end

def divide!(a, b) do
	# make the division
end

Definition

Sum type

Sum type

type animal = "cat" | "dog" | "cow";

Sum type

type option(int) = 
  | None 
  | Some(int);

Product type

Product type

type dice_value = 1 | 2 | 3 | 4 | 5 | 6;
type player = "Alice" | "Bob"

type roll_of_dice = {
  player: player,
  value: dice_value
}

roll_of_dice = dice_value * player

An algebraic type is a sum type of product type

An algebraic is a potential recursive sum type of product type

type intList =
  | Empty
  | Node({
      value: int,
      next: intList,
    });

Avoid avoidable complexity

Accidental complexity

type state = {
  isLoading: bool,
  error: error | null,
  data: data | null
}

Accidental complexity

clap now!

deck

By Romain Commandé