Системы типов

в двух словах

Вячеслав Шебанов

Disclaimer

Зачем нужны типы?

Слово (Word)

1011010001001010100011110101010

Слова имеют смысл

Но этот смысл задается внешней системой

Типы появляются естественным образом

лорд Бертран Рассел

Пусть в некой деревне живёт  брадобрей, который бреет всех жителей деревни, которые не бреются сами, и только их.

 

Бреет ли брадобрей сам себя?

Парадокс Брадобрея

Теория типов Рассела

Примитивные типы


let isDone: boolean = false;


let someNumber: number = 10;

Давид Гильберт

Entscheidungsproblem

Проблема разрешимости

Можем ли мы, описав некое утверждения специальным образом, ответить на вопрос с помощью общего метода является ли это утверждение истиной всегда

Алонзо Черч

λ-исчисление

  • x, y, a-z — переменная
  • M, N, A-Z — терм (выражение)
  • λx.M — абстракция (анонимная функция)
  • (M N) — применение (вызов функции)

λ-исчисление

(λx . x) z
(λx . x) z → z
(λx. x) (λx. x)
(λx. x) (λx. x) (λx. x)

Identity function

function identity(x) {
  return x;
}

А как же типы?

Простое типизированное λ-исчисление

λ→

(λx:Bool . x):Bool

Simply-Typed Lamda Calculus

function identity(x: number): number {
  return x;
}
(λx:Int y:Int . x * y): Int
function mult(x: number, y: number): number {
  return x * y;
}

Полиморфизм

function saySomething(cat: Cat) {
  return 'Meow';
}

function saySomething(dog: Dog) {
  return 'Woof';
}
function saySomething(cat: Cat) {
  return 'Meow';
}

function saySomething(dog: Dog) {
  return 'Woof';
}

> saySomething(cat);
"Meow"

> saySomething(dog);
"Woof"
function identity<T>(arg: T): T {
    return arg;
}

System F

Жирар 1972, Рейнольдс 1974

Абстракция на типах

λx:Bool . x

λX. λx:X. x

Абстракция на типах

id = λX. λx:X. x

Абстракция на типах

|> id : ∀X. X → X

Абстракция на типах

(λX. λx:X. x) Bool

Абстракция на типах

λx:Bool. x

Дженерики в Go

var x []int
// intSum has type func([]int) int
intSum := Sum(int)
total := intSum(x)

*вы находитесь здесь*

Soundness

  • Прогресс
  • Сохранение типов

Прогресс

(λx:Int y:Int . x * y) a b

Если a и b это Int

Сохранение типов

(λx:Int y:Int . x * y) a b 
→ 
a * b

Когда добавляешь новую фичу в язык

Java and Scala’s Type Systems are Unsound 

(2016 Amin, Tate)

Вернемся в 1937

Алан Тьюринг

Проблема останова

Даны описание процедуры и её начальные входные данные, требуется определить, завершится ли когда-либо выполнение процедуры с этими данными.

Тезис Черча-Тьюринга

Любая функция, которая может быть вычислена физическим устройством, может быть вычислена машиной Тьюринга

Тьюринг-полнота

Строгая нормализация

Простое типизированное лямбда-исчисление

System F

Тотальность

Тотальной называется такая функция, которая гарантированно завершается за конечное количество шагов и определена на всех разрешенных входных параметрах

Тотальность

Никаких рантайм ошибок

Что дальше?

Хенк Барендрехт

λ-куб

Значения зависят от значений

function identity(x: Bool): Bool {
  return x;
}

Значения зависят от типов

function identity<T>(x: T): T {
  return x;
}

Типы зависят от типов

function List(ty: Type): Type {
  return Array<ty>;
}

function list<T>(x: T): List(T) {
  return [x];
}

Типы зависят от значений

function random(n: Nat) : Fin<n> {
  return ...;
}

Верификация ПО

Что это значит?..

Можно писать код без ошибок!

Послесловие

За пределами доклада

  • Сабтайпинг
  • Линейные типы (Rust)
  • Сессионные типы
  • HoTT

С чего начать?

Ссылки

normal

Ссылки

hard

Ссылки

nightmare

Конец

Twitter: @thought_sync

Зависимые типы

за 5 минут

function zip<T1, T2>(list1: Array<T1>, list2: Array<T2>): Array<Pair<T1, T2>> {
    if (list1.length !== list2.length) {
		throw Error('Arrays lengths are not equal');
    }
    let result = [];
    for (let i = 0; i < list1.length; i++) {
        result[i] = pair(list1[i], list2[i]);
    }

    return result;
}
function zip<T1, T2>(list1: Array<T1>, list2: Array<T2>)
Array<Pair<T1, T2>>
if (list1.length !== list2.length) {
  throw Error('Arrays lengths are not equal');
}
let result = [];
for (let i = 0; i < list1.length; i++) {
    result[i] = pair(list1[i], list2[i]);
}

return result;

Более точный тип

Vect<T, n>

T — тип элемента

n — кол-во элементов

function zip<T1, T2>(v1: Vect<T1, n>, v2: Vect<T2, n>): Vect<Pair<T1, T2>, n> {
    let result = [];
    for (let i = 0; i < n; i++) {
        result[i] = pair(v1[i], v2[i]);
    }
    return result;
}
function zip<T1, T2>(v1: Vect<T1, n>, v2: Vect<T2, n>)
Vect<Pair<T1, T2>, n>

Откуда берутся вектора?

function vectToList<T>(list: Array<T>) : DPair(n: Nat, Vect<T, n>) {
    return dpair(list.length, toVect(list));
}
function vectToList<T>(list: Array<T>)
DPair(n: Nat, Vect<T, n>)

Зависимая пара

return dpair(list.length, toVect(list));
plusAssoc : plus n (plus m o) = plus (plus n m) o

Ассоциативность

Системы типов в двух словах

By Slava Shebanov

Системы типов в двух словах

  • 3,800