Словарь языка
Весь flang одним листингом: 128 форм, 310 написаний, 46 конструкций — и у каждой сказано, что она делает.
Это страница для вычитки, а не для поиска одной формы. Ничего не свёрнуто и не спрятано: язык лежит подряд, сверху вниз, в том порядке и по тем разделам, которыми размечена таблица ключевых слов самого лексера — их 7. Если нужен работающий пример, который открывается в песочнице нажатием, он в справочнике конструкций: там та же 46 карточка, только с кодом и кнопкой.
Ни одна строка ниже не написана в шаблоне. Формы и все их написания приезжают из таблицы static/js/vendor/flang/lexer.js, разделы — из её собственной разметки, пояснения — из заголовков примеров static/fts/models/ref/. Появилась в языке форма, которой здесь нет, — падает npm test, а не тихо стареет страница.
Все формы языка
По разделам таблицы лексера. В строке — все написания формы: русские и английские равноправны, компилятор принимает любое. Справа — конструкция, которая эту форму объясняет.
документ и модульностьформ 10 · написаний 23
moduleмодульmoduleМодуль: имя файла и его экспортexportsэкспортируетexportsМодуль: имя файла и его экспортusesиспользуетusesИмпорт: использует «…» из "…" только «…»categoryкатегорияcategoryКатегория: предметная область и её объектыobjectобъектструктураobjectstructureЗапись: объект «…» и его поляrecordзаписьrecordЗапись: объект «…» и его поляtypeтипtypeСумма типов: тип «…» и его вариантыvariantвариантvariantСумма типов: тип «…» и его вариантыaliasэтоИмя для типа: тип «…» это список «…»nestedвложен объектвложена структураnested objectnested structureВложенный объект: вложен объект «…»
функцииформ 7 · написаний 14
totalтотальнаяtotalФункция: принимает, возвращает, телоfunctionфункцияfunctionФункция: принимает, возвращает, телоacceptsпринимаетacceptsФункция: принимает, возвращает, телоreturnsвозвращаетreturnsФункция: принимает, возвращает, телоexampleпримерexampleПример: тест внутри объявленияgivenданоgivenПример: тест внутри объявленияexpectedожидаетсяexpectedПример: тест внутри объявления
выраженияформ 17 · написаний 38
letпустьletЛокальное имя: пусть … равно …ifеслиifВетвление: если … то … иначе …thenтоthenВетвление: если … то … иначе …elseиначеelseВетвление: если … то … иначе …matchразборmatchРазбор списка: разбор … случай пусто … случай голова и хвост …caseслучайcaseРазбор списка: разбор … случай пусто … случай голова и хвост …ofотofВызов функции: «Имя» от аргумента и аргументаandиandВызов функции: «Имя» от аргумента и аргументаwithсwithСклейка и разбиение: соединить … с …, разделить … по …fromизfromИмпорт: использует «…» из "…" только «…»onlyтолькоonlyИмпорт: использует «…» из "…" только «…»toвкtointoinontoСписки: пустой список, список из …, добавить … к …byпоbyСклейка и разбиение: соединить … с …, разделить … по …atуatДоступ к полю: поле «…» у значенияasкакasОбразцы варианта: случай вариант «…» с «…» как …, случай любоеwhereгдеwhereОтбор: отфильтровать … где имя → условиеstartingWithначиная сstarting withСвёртка: свёртка … начиная с … как накопитель и элемент → выражение
встроенные формыформ 24 · написаний 49
mapотобразитьmapОтображение: отобразить … как имя → выражениеfilterотфильтроватьfilterОтбор: отфильтровать … где имя → условиеfoldсвёрткасверткаfoldСвёртка: свёртка … начиная с … как накопитель и элемент → выражениеlengthдлинаlengthГолова, хвост, длинаcharсимволcharСимвол и подстрока: символ … в …, подстрока … с … по …decomposeразложитьdecomposeРазложение строки: разложить … на символыintoCharactersна символыinto charactersРазложение строки: разложить … на символыsubstringподстрокаsubstringСимвол и подстрока: символ … в …, подстрока … с … по …joinсоединитьjoinСклейка и разбиение: соединить … с …, разделить … по …splitразделитьsplitСклейка и разбиение: соединить … с …, разделить … по …containsсодержитcontainsПроверки строки: содержит, начинается сbeginsWithначинается сbegins withПроверки строки: содержит, начинается сtoNumberOrFailк числу или бедаto number or failureПревращения: к числу, к строке, к числу или бедаtoNumberк числуto numberПревращения: к числу, к строке, к числу или бедаtoTextк строкеto textПревращения: к числу, к строке, к числу или бедаheadголоваheadГолова, хвост, длинаtailхвостtailГолова, хвост, длинаheadTailголова и хвостhead and tailРазбор списка: разбор … случай пусто … случай голова и хвост …emptyпустоemptyРазбор списка: разбор … случай пусто … случай голова и хвост …emptyListпустой списокempty listСписки: пустой список, список из …, добавить … к …listOfсписок изlist ofСписки: пустой список, список из …, добавить … к …listсписокlistИмя для типа: тип «…» это список «…»addдобавитьaddСписки: пустой список, список из …, добавить … к …anyлюбоеanyОбразцы варианта: случай вариант «…» с «…» как …, случай любое
арифметика и сравненияформ 12 · написаний 41
opAddплюсplusАрифметика: плюс, минус, умножить на, делить на, остаток отopSubминусminusАрифметика: плюс, минус, умножить на, делить на, остаток отopMulумножить наtimesmultiplied byАрифметика: плюс, минус, умножить на, делить на, остаток отopDivделить наdivided byАрифметика: плюс, минус, умножить на, делить на, остаток отopModостаток отmoduloАрифметика: плюс, минус, умножить на, делить на, остаток отopPercentпроцентовпроцентапроцентpercentpercentsПравило: условие и одно действиеcmpEqравенравнаравноравнымравнойравноеequalsequal toСравнения: шесть и только шестьcmpNeqне равенне равнане равноis not equal tonot equalsСравнения: шесть и только шестьcmpGtбольшеis greater thangreater thanСравнения: шесть и только шестьcmpLtменьшеis less thanless thanСравнения: шесть и только шестьcmpLteне большеis at mostat mostСравнения: шесть и только шестьcmpGteне меньшеis at leastat leastСравнения: шесть и только шесть
значения и типыформ 11 · написаний 39
litTrueдаtrueyesЛитералы: да, нет, ничтоlitFalseнетfalsenoЛитералы: да, нет, ничтоlitNullничтоnullЛитералы: да, нет, ничтоtNumberчислочислачисломчислуnumberТипы полей: строка, число, деньги, дата, признак, состояниеtStringстрокастрокистрокойстрокутекстомstringТипы полей: строка, число, деньги, дата, признак, состояниеtFlagпризнакпризнакапризнакомbooleanflagТипы полей: строка, число, деньги, дата, признак, состояниеtMoneyденьгиденьгамиmoneyТипы полей: строка, число, деньги, дата, признак, состояниеtDateдатадатыдатудатойdateТипы полей: строка, число, деньги, дата, признак, состояниеstateсостояниесостояниемstateПроцесс: состояние, начальное значение, сообщения, обработчикisявляетсяisКатегория: предметная область и её объектыmaybeIsиногда являетсяmay beТипы полей: строка, число, деньги, дата, признак, состояние
наследие FTSформ 47 · написаний 106
utilityутилитаutilityУтилита: вход, тип результата и стартовое значениеruleправилоruleПравило: условие и одно действиеpropertyсвойствоpropertyСвойство: постусловие обо всех входахresultрезультатresultСвойство: постусловие обо всех входахstartsWithначинает сstarts withУтилита: вход, тип результата и стартовое значениеfieldполеполяfieldДоступ к полю: поле «…» у значенияmorphismморфизмmorphismМорфизм-стрелка: морфизм «…» из «…» в «…»afterпослеafterКомпозиция: после, цепочка, единицаchainцепочкаchainКомпозиция: после, цепочка, единицаfirstStepсначалаfirstКомпозиция: после, цепочка, единицаnextStepзатемnextКомпозиция: после, цепочка, единицаidentityединицаidentityКомпозиция: после, цепочка, единицаisomorphismизоморфизмisomorphismИзоморфизм: два представления одного и того жеforwardMorphismпрямой морфизмforward morphismИзоморфизм: два представления одного и того жеinverseMorphismобратный морфизмinverse morphismИзоморфизм: два представления одного и того жеmonoidмоноидmonoidМоноид и группа: закон вместо соглашенияcarrierносительcarrierМоноид и группа: закон вместо соглашенияoperationоперацияoperationМоноид и группа: закон вместо соглашенияinverseElementобратный элементinverse elementМоноид и группа: закон вместо соглашенияmonadмонадаmonadМонада: связывание вместо лестницы разборовmonadUnitвозвратreturnМонада: связывание вместо лестницы разборовmonadJoinсоединениеflattenМонада: связывание вместо лестницы разборовinMonadв монадеin monadМонада: связывание вместо лестницы разборовtheoremтеоремаtheoremТеорема: утверждение о данных, которое проверяетсяfunctorфункторfunctorФунктор: отображение одной категории в другуюbifunctorбифункторbifunctorБифунктор: перевод, у которого два входаobjectPairобъектыobjectsБифунктор: перевод, у которого два входаmorphismPairморфизмыmorphismsБифунктор: перевод, у которого два входаpropositionутверждениеpropositionУтверждение: фигурная поверхность и свидетельство в данныхhasимеетhasТеорема: утверждение о данных, которое проверяетсяinDataв данныхin dataТеорема: утверждение о данных, которое проверяетсяfindWhereнайти гдеfind whereТеорема: утверждение о данных, которое проверяетсяbyMorphismпо морфизмузатем по морфизмуприменить морфизмзатем применить морфизмby morphismthen by morphismapply morphismthen apply morphismТеорема: утверждение о данных, которое проверяетсяthereforeследовательнополучаемthereforeТеорема: утверждение о данных, которое проверяетсяlawпо законуunder lawТеорема: утверждение о данных, которое проверяетсяmapsToотображается вотображаются вmaps tomap toФунктор: отображение одной категории в другуюmapsToFieldотображается в полеmaps to fieldФунктор: отображение одной категории в другуюmapsToMorphismотображается в морфизмотображаются в морфизмmaps to morphismmap to morphismФунктор: отображение одной категории в другуюprocessпроцессprocessПроцесс: состояние, начальное значение, сообщения, обработчикhandlesобрабатываетhandlesПроцесс: состояние, начальное значение, сообщения, обработчикbudgetс запасомwith budgetЗапас витков: с запасом … витковsupervisionнадзорsupervisionНадзор: стратегия на процесс и порог отказовstrategyстратегияstrategyНадзор: стратегия на процесс и порог отказовfailureThresholdпорог отказовfailure thresholdНадзор: стратегия на процесс и порог отказовrunпрогонrunПрогон: семя, входящие сообщения, ожидаемое состояниеseedсемяseedПрогон: семя, входящие сообщения, ожидаемое состояниеplanпланplanПлан: продолжение, записанное значением
Все конструкции и что они делают
46 конструкций покрывают все 128 форм: каждая форма принадлежит ровно одной конструкции, и это стережёт сборка справочника. Пояснение взято из заголовка примера, который лежит рядом с кодом.
Файл, модуль и типыиз чего состоит программа · конструкций 5
-
Имя для типа: тип «…» это список «…»
этосписокlistСлово «это» даёт имя уже существующему типу — чаще всего списку. Имя типа после этого можно писать вместо «список «Позиция»» везде, где раньше приходилось повторять всю запись целиком.
-
Модуль: имя файла и его экспорт
модульmoduleэкспортируетexportsЗаголовок называет файл и перечисляет, что он отдаёт наружу. Пространств имён в языке нет: импорт — это слияние объявлений, поэтому имя, вынесенное в «экспортирует», становится общим и обязано быть уникальным.
-
Запись: объект «…» и его поля
объектструктураobjectstructureзаписьrecordЗапись — произведение: набор полей с типами. Слова «объект» и «запись» означают здесь одно и то же (в модели FTS то же самое пишут словом «структура»), а имя типа поля — часть контракта и потому точное.
-
Сумма типов: тип «…» и его варианты
типtypeвариантvariantСумма перечисляет случаи, и у каждого — свои поля. Дальше компилятор следит, чтобы разбор покрывал все варианты: забытый случай — ошибка проверки FLANG_MATCH_NOT_EXHAUSTIVE, а не необработанное значение в проде.
-
Импорт: использует «…» из "…" только «…»
используетusesтолькоonlyизfromЕдинственная конструкция языка, которой нужен диск. Пример проверяется командой: `flang check` рядом с файлом читает module.flang, связывает и прогоняет примеры — это и записано в отчёте npm test. «Только» сужает импорт до перечисленных имён: без него модуль вносит все свои, и одного совпадения хватит, чтобы связывание отказало.
Функции и примерыобъявление, вызов, тест внутри · конструкций 3
-
Вызов функции: «Имя» от аргумента и аргумента
отofиandВызов пишется предлогом: «Имя» от X. Второй и следующие аргументы присоединяются словом «и». Функции не являются значениями: передать функцию в функцию нельзя, и это плата за печать в языки без замыканий.
-
Пример: тест внутри объявления
примерexampleданоgivenожидаетсяexpectedПример — часть функции, а не отдельный файл рядом. «Дано» задаёт аргумент по имени, «ожидается» — результат. Их выполняет `flang test`, и они же выполняются на этой странице во вкладке «Примеры».
-
Функция: принимает, возвращает, тело
тотальнаяtotalфункцияfunctionпринимаетacceptsвозвращаетreturnsОбъявление из трёх строк: имя, что принимает, что возвращает. Дальше — тело, одно выражение. Слово «тотальная» — обещание завершения, и компилятор его проверяет: не доказал убывания — FLANG_NOT_TOTAL, а не предупреждение.
Выраженияветвление, разбор, локальные имена · конструкций 5
-
Доступ к полю: поле «…» у значения
полеполяfieldуatДва способа взять поле записи, оба читаются вслух: точка после значения и оборот «поле … у …». Имя поля — часть контракта записи, поэтому оно точное: падежного подбора здесь нет, в отличие от локальных имён.
-
Ветвление: если … то … иначе …
еслиifтоthenиначеelseВетвление — выражение, а не оператор: у него есть значение, поэтому «иначе» обязательно. Ветви обязаны быть одного типа — иначе FLANG_TYPE, и это проверяется до запуска, а не на первом же неудачном входе.
-
Локальное имя: пусть … равно …
пустьletИмя живёт до конца выражения и не меняется. Переприсваивания в языке нет вовсе: второе «пусть» с тем же именем — это другое имя в другой области, поэтому читать функцию можно сверху вниз, ничего не удерживая в голове.
-
Разбор списка: разбор … случай пусто … случай голова и хвост …
разборmatchслучайcaseпустоemptyголова и хвостhead and tailЦикла в языке нет; список обходится разбором на пустой и «голова и хвост». Хвост — часть исходного значения, поэтому рекурсия по нему структурно убывает, и «тотальная» доказывается. Незакрытый случай — не забытая ветка на проде, а FLANG_MATCH_NOT_EXHAUSTIVE при проверке.
-
Образцы варианта: случай вариант «…» с «…» как …, случай любое
любоеanyкакasОбразец варианта связывает поля новыми именами прямо в строке «случай». «Любое» ловит остальные случаи, и оно же — единственный способ дать значению имя, не разбирая его. Ставить «любое» первым бессмысленно: следующий случай станет недостижимым, и это ошибка FLANG_MATCH_UNREACHABLE.
Спискивместо циклов · конструкций 5
-
Отбор: отфильтровать … где имя → условие
отфильтроватьfilterгдеwhereТело после стрелки обязано вернуть признак — иначе FLANG_TYPE. Порядок элементов сохраняется, исходный список не меняется: отбор возвращает новый.
-
Свёртка: свёртка … начиная с … как накопитель и элемент → выражение
свёрткасверткаfoldначиная сstarting withСвёртка заменяет цикл со счётчиком: накопитель и элемент — два имени, и после стрелки написано, чем накопитель станет. Начальное значение называет автор, а не подставляет рантайм, — тот же принцип, что у «начинает с» в утилите FTS.
-
Голова, хвост, длина
головаheadхвостtailдлинаlengthТри встроенные формы над списком. «Длина» работает и над строкой — там она считает кодовые точки, а не единицы UTF-16, поэтому кириллица и эмодзи считаются по-человечески.
-
Списки: пустой список, список из …, добавить … к …
пустой списокempty listсписок изlist ofдобавитьaddвкtointoinontoСписок однороден: тип элемента объявляется один раз («список числа») и дальше проверяется. «Добавить» ничего не меняет на месте — оно возвращает новый список, потому что значения в языке неизменяемы.
-
Отображение: отобразить … как имя → выражение
отобразитьmapФункции не значения первого класса, поэтому «отобразить» принимает ТЕЛО, а не функцию: имя элемента и выражение после стрелки. Из-за этого форма печатается в C и Go без замыканий, а завершение остаётся доказуемым.
Строкистрока как данные · конструкций 5
-
Превращения: к числу, к строке, к числу или беда
к числуto numberк строкеto textк числу или бедаto number or failure«К строке» от признака даёт «да» или «нет», а не true/false: поверхность языка русская, и все восемь целей печати обязаны повторять именно её. «К числу» на непригодной строке прекращает вычисление целиком. Форма «к числу или беда» отказать не может вовсе: она возвращает «Разобрано» со значением либо «Не разобрано» с кодом и текстом — теми же, какими отказала бы «к числу». Тип «Исход числа» приписывает программе сам язык, объявлять его не нужно.
-
Разложение строки: разложить … на символы
разложитьdecomposeна символыinto charactersФорма из двух слов, а не одно слово «символы»: ключевое слово запрещает имя, а «символы» люди используют как имя переменной. Нужна она не для краткости — проход по индексу убывает по числу, а число анализ завершаемости частью значения не считает; разложенная в список строка обходится рекурсией по хвосту, и «тотальная» доказывается.
-
Склейка и разбиение: соединить … с …, разделить … по …
соединитьjoinразделитьsplitпоbyсwith«Соединить X с Y» склеивает две строки, «соединить части по разделителю» — список. Обратная форма — «разделить текст по разделителю»; предлог у пары один и тот же, чтобы её было видно как пару.
-
Символ и подстрока: символ … в …, подстрока … с … по …
символcharподстрокаsubstringИндексация строк — с единицы и включительно с обоих концов: «первый символ» это первый, а не нулевой. Решение записано в спецификации языка и одинаково во всех восьми целях печати.
-
Проверки строки: содержит, начинается с
содержитcontainsначинается сbegins withОбе формы возвращают признак и работают там же, где любое другое условие, — в «если», в отборе и в свойстве утилиты. «Содержит» работает и над списком: это одна встроенная форма на два вида значений.
Числа, сравнения, литералыарифметика и шесть сравнений · конструкций 3
-
Арифметика: плюс, минус, умножить на, делить на, остаток от
плюсplusминусminusумножить наtimesmultiplied byделить наdivided byостаток отmoduloЧисла — IEEE-754 double, как в ядре FTS: расхождение по арифметике с уже напечатанным кодом недопустимо. Деление на ноль даёт бесконечность, а не ошибку, — печать в JavaScript обязана давать то же самое значение.
-
Сравнения: шесть и только шесть
равенравнаравноравнымравнойравноеequalsequal toне равенне равнане равноis not equal tonot equalsбольшеis greater thangreater thanменьшеis less thanless thanне большеis at mostat mostне меньшеis at leastat leastСравнений в языке ровно шесть: равен, не равен, больше, меньше, не больше, не меньше. Седьмого нет, и придумать его нельзя — компилятор откажет с номером строки. Равенство скаляров — Object.is, списки и записи сравниваются структурно.
-
Литералы: да, нет, ничто
даtrueyesнетfalsenoничтоnullПризнак записывается словами «да» и «нет», пустое значение — «ничто». В английской записи это true/false/null и yes/no, и обе поверхности дают один и тот же AST: файл на русском и файл на английском компилируются в одно.
Модель FTSкатегория, утилита, правило, свойство · конструкций 6
-
Категория: предметная область и её объекты
категорияcategoryявляетсяisПервая строка модели FTS. Всё остальное лежит внутри отступом — скобок и точек с запятой в языке нет. Категория задаёт границу разговора: имена внутри неё уникальны, а объект — это данные с типами.
-
Вложенный объект: вложен объект «…»
вложен объектвложена структураnested objectnested structureПоле, у которого имя и тип — один и тот же объект. Это единственный способ сложить в модель составные данные, не выдумывая для поля второе имя: адрес внутри заказа так и называется адресом.
-
Свойство: постусловие обо всех входах
свойствоpropertyрезультатresultСвойство проверяется после всех правил и говорит о результате. Нарушено — выполнение останавливается с FTS_UTILITY_PROPERTY, а не подрезает число до «безопасного» втихую. Пример — проверка на один вход, свойство — на все: поменяйте потолок на 1000 и посмотрите, как второй пример перестанет считаться вовсе.
-
Правило: условие и одно действие
правилоruleпроцентовпроцентапроцентpercentpercentsСрабатывают ВСЕ правила, чьи условия истинны, и складываются: это не цепочка if / else if. Условия соединяются словом «и». Проценты считаются от поля: «10 процентов от поля сумма» — дословно та же формула, что уедет в напечатанный код.
-
Типы полей: строка, число, деньги, дата, признак, состояние
строкастрокистрокойстрокутекстомstringчислочислачисломчислуnumberденьгиденьгамиmoneyдатадатыдатудатойdateпризнакпризнакапризнакомbooleanflagиногда являетсяmay beВстроенных типов пять, и шестой — «состояние»: именованный признак, которым пользуются морфизмы и теоремы. «Иногда является» делает поле необязательным: значение может отсутствовать, и модель об этом сказала вслух.
-
Утилита: вход, тип результата и стартовое значение
утилитаutilityначинает сstarts withТри строки обязательны: что принимает, что возвращает и с чего начинает. Ноль в «начинает с» пишет автор модели, а не подставляет рантайм — без этой строки компилятор откажет с FTS_UTILITY_INITIAL. Утилита — это будущая функция: `flang emit` печатает её в восемь языков.
Категории и морфизмыстрелки, теоремы, функторы · конструкций 9
-
Бифунктор: перевод, у которого два входа
бифункторbifunctorобъектыobjectsморфизмыmorphismsФунктор переводит одну категорию в другую, бифунктор — две сразу: ключ отображения не имя, а ПАРА имён. Так описывают всё, что берёт две вещи и делает третью: пару значений, «либо одно, либо другое», словарь ключей и значений. Законы проверяются тем же способом, что у функтора, и это важнее самой формы: морфизм в языке — ОБЪЯВЛЕНИЕ, домен и кодомен известны до запуска, поэтому «образ композиции есть композиция образов» решается сличением имён — без сетки входов, без вычислений, без решателя.
-
Композиция: после, цепочка, единица
послеafterцепочкаchainсначалаfirstзатемnextединицаidentity«В после А» — композиция в математическом порядке: правая применяется первой. Читать её на четырёх звеньях невозможно, поэтому та же композиция записывается цепочкой в порядке чтения. Композиция разрешена ровно тогда, когда кодомен предыдущей стрелки совпал с доменом следующей, — иначе компилятор откажет. «Единица» — тождественная стрелка объекта: без неё не сформулировать законы функтора.
-
Функтор: отображение одной категории в другую
функторfunctorотображается вотображаются вmaps tomap toотображается в полеmaps to fieldотображается в морфизмотображаются в морфизмmaps to morphismmap to morphismФунктор переводит объекты в объекты, поля в поля и морфизмы в морфизмы — целиком, а не «примерно». Именно поэтому переход между двумя моделями (запрос списка и хранилище, скидки и подписки) можно проверить, а не пересказать в комментарии.
-
Изоморфизм: два представления одного и того же
изоморфизмisomorphismпрямой морфизмforward morphismобратный морфизмinverse morphismИзоморфизм заявляет, что две записи — это одна вещь в двух видах: туда и обратно без потерь. Проверяется именно это, а не благое намерение: стрелки обязаны сходиться концами крест-накрест, и у каждого конца обязана быть объявлена единица — иначе «вернулись к тому же» не о чем сказать. Заявление сильное, поэтому его дешевле проверить, чем поверить: потеря поля при переводе туда-обратно — ошибка, которую в работающей системе ищут долго.
-
Монада: связывание вместо лестницы разборов
монадаmonadвозвратreturnсоединениеflattenв монадеin monadМонада объявляется НА типе, как моноид — на носителе: «возврат» называет η, «соединение» — μ, и обе строки указывают на обычные тотальные функции. Блок «в монаде» — то, ради чего форма и заведена: каждое «пусть» связывает шаг, который вправе не дать ответа, а «возврат» обязан стоять последней строкой. Ниже стоят рядом две функции, считающие одно и то же: первая формой, вторая — вложенным разбором, в который форма разворачивается. Форма не добавляет языку силы, она убирает лестницу «случай «Нет» то вариант «Нет»», которая растёт на каждый шаг и в которой ошибаются.
-
Моноид и группа: закон вместо соглашения
моноидmonoidносительcarrierоперацияoperationобратный элементinverse elementМоноид — это множество, операция на нём и единица, а группа — моноид, у которого есть обращение. Отдельного слова для группы нет намеренно: приписал «обратный элемент» — получил группу. Устройство доказывается по объявлениям: операция обязана быть функцией двух значений носителя в носитель, единица — значением носителя. Законы — ассоциативность, нейтральность, обратимость — проверяются на конечной сетке из примеров, и при нарушении компилятор называет тройку, на которой не сошлось.
-
Морфизм-стрелка: морфизм «…» из «…» в «…»
морфизмmorphismОбъекты категории — это типы, морфизм — стрелка между ними. Стрелка не выполняет переход: она объявляет, что он допустим, и даёт компилятору право проверять стыковку. Равенство типов номинальное — по имени, поэтому «Заказ» и «Отгрузка» не перепутаются, даже если поля у них совпадут.
-
Утверждение: фигурная поверхность и свидетельство в данных
утверждениеpropositionУ FTS две поверхности: отступная, которой написано всё остальное на этой странице, и фигурная — та же модель в скобках. Слово «утверждение» живёт только во второй: оно называет, каким свидетельством подтверждается факт и где это свидетельство лежит. Обе поверхности компилируются в один документ, поэтому вкладка «Доказательство» работает и здесь.
-
Теорема: утверждение о данных, которое проверяется
теоремаtheoremимеетhasв данныхin dataнайти гдеfind whereпо морфизмузатем по морфизмуприменить морфизмзатем применить морфизмby morphismthen by morphismapply morphismthen apply morphismследовательнополучаемthereforeпо законуunder lawЧетыре строки теоремы читаются как рассуждение: что дано, где искать свидетельство, каким морфизмом идём и что получаем. Строка «в данных» — самая важная: она превращает рассуждение в проверяемое утверждение, называя место факта. Морфизм здесь — импликация с объявленным законом: он не выполняет переход, а утверждает его допустимость.
Процессысостояние, надзор, прогон · конструкций 5
-
Запас витков: с запасом … витков
с запасомwith budgetОбработчик, завершение которого не доказано, обязан назвать запас витков — без строки «с запасом» программа не собирается, и это ошибка проверки, а не предупреждение. Исчерпание — определённый исход: сообщение отвергнуто, состояние осталось прежним (обработчик чист, половины изменения не бывает).
-
План: продолжение, записанное значением
планplanПлан — это программа, которая ЖДЁТ: читает файл, ходит в сеть, пишет ответ. Ни одна строка ниже ничего из этого не делает. Каждая строит ЗНАЧЕНИЕ, описывающее следующий ход, а исполняет его хозяин — среда, в которую модуль напечатан. Отсюда свойство, которое обычно теряется вместе с чистотой: функции плана ТОТАЛЬНЫ. Программа, ходящая в сеть, доказано завершается — потому что сеть в неё не входит. Завершается описание; ждёт хозяин. И потому же каждый ход проверяется обычным примером, без файлов и сокетов. Замыканий в языке нет, поэтому продолжение не спрятано, а названо: варианты «Хода» — это точки, в которых программа ждёт.
-
Процесс: состояние, начальное значение, сообщения, обработчик
процессprocessобрабатываетhandlesсостояниесостояниемstateСостояние принадлежит одному процессу, и трогать его снаружи нельзя. Всё, что процесс умеет, — принять сообщение и вернуть «новое состояние плюс список действий»; обработчик при этом остаётся обычной чистой функцией, которую проверяют примеры. Отправка описывается, а не выполняется: исполняет её планировщик.
-
Прогон: семя, входящие сообщения, ожидаемое состояние
прогонrunсемяseedПример конкурентной программы — это семя планировщика, список сообщений и ожидаемый итог. Семя делает чередование воспроизводимым: тот же прогон на том же семени даёт тот же ответ. Итог, который зависит от чередования, — признак неверной программы, а не недостаток проверки, поэтому второй прогон повторяет первый на другом семени и ждёт того же.
-
Надзор: стратегия на процесс и порог отказов
надзорsupervisionстратегияstrategyпорог отказовfailure thresholdНадзор объявляется данными, а не кодом: у каждого поднадзорного процесса — своя стратегия, а порог отказов говорит, когда сдаваться и передавать выше. «Порог отказов» — форма из двух слов не для красоты: одиночное «порог» уже живёт именем параметра в стандартной библиотеке, а ключевое слово запрещает имя.