Подтвердить что ты не робот

Что является типичным?

Что относится к TypeState в отношении дизайна языка? Я видел, как это упоминалось в некоторых дискуссиях относительно нового языка с помощью mozilla под названием Rust.

4b9b3361

Ответ 1

Примечание. Typestate был удален из Rust, осталась только ограниченная версия (отслеживание неинициализировано и перемещено из переменных). См. Мою записку в конце.

Мотивация для TypeState заключается в том, что типы неизменяемы, однако некоторые из их свойств являются динамическими, для каждой переменной.

Идея состоит в том, чтобы создать простые предикаты о типе и использовать анализ Control-Flow, который компилятор выполнил по многим другим причинам, чтобы статически украсить тип этими предикатами.

Эти предикаты на самом деле не проверяются самим компилятором, это может быть слишком обременительным, вместо этого компилятор просто рассуждает в терминах графика.

В качестве простого примера вы создаете предикат even, который возвращает true, если число четное.

Теперь вы создаете две функции:

  • halve, который действует только на номера even
  • double, которые принимают любое число и возвращают число even.

Обратите внимание, что тип number не изменяется, вы не создаете тип evennumber и дублируете все те функции, которые ранее действовали на number. Вы просто сочиняете number с предикатом под названием even.

Теперь построим несколько графиков:

a: number -> halve(a)  #! error: `a` is not `even`

a: number, even -> halve(a)  # ok

a: number -> b = double(a) -> b: number, even

Простой, не так ли?

Конечно, это немного усложняется, если у вас есть несколько возможных путей:

a: number -> a = double(a) -> a: number, even -> halve(a) #! error: `a` is not `even`
          \___________________________________/

Это показывает, что вы рассуждаете в терминах наборов предикатов:

  • при объединении двух путей новый набор предикатов является пересечением множеств предикатов, заданных этими двумя путями

Это может быть дополнено общим правилом функции:

  • для вызова функции, необходимо выполнить множество предикатов, которые она требует.
  • после вызова функции выполняется только установленное множество предикатов (примечание: аргументы, принятые по значению, не затрагиваются)

И, таким образом, строительный блок TypeState в Rust:

  • check: проверяет, что предикат выполняется, если он не fail, в противном случае добавляет предикат к набору предикатов

Обратите внимание, что поскольку Rust требует, чтобы предикаты были чистыми функциями, он может устранить избыточные вызовы check, если он может доказать, что предикат уже выполняется в этой точке.


Какой недостаток Typestate прост: способность к компоновке.

Если вы внимательно прочитаете описание, вы заметите следующее:

  • после вызова функции выполняется только установленное множество предикатов (примечание: аргументы, принятые по значению, не затрагиваются)

Это означает, что предикаты для типов бесполезны сами по себе, утилита исходит из функций аннотирования. Таким образом, введение нового предиката в существующую кодовую базу представляет собой отверстие, так как существующие функции необходимо пересмотреть и настроить, чтобы объяснить, нужны ли они/сохраняют инвариант.

И это может привести к дублированию функций с экспоненциальной скоростью при появлении новых предикатов: предикаты, к сожалению, не могут быть скомпонованы. Сама проблема дизайна, которую они должны были решать (распространение типов, таким образом, функции), похоже, не рассматривается.

Ответ 2

В основном это расширение типов, где вы не просто проверяете, разрешена ли какая-либо операция вообще, но в этом конкретном контексте. Все это во время компиляции.

Оригинальная бумага на самом деле вполне читаема.

Ответ 3

Там есть сценарий, написанный для Java, и пояснительная страница Adam Warski дает некоторую полезную информацию. Я просто вычисляю этот материал самостоятельно, но если вы знакомы с QuickCheck для Haskell, приложение QuickCheck для монадического состояния похоже похоже: классифицируйте состояния и объясните, как они меняются, когда они мутируются через интерфейс.