DigitableCourses

Словарь языка

Весь flang одним листингом: 128 форм, 310 написаний, 46 конструкций — и у каждой сказано, что она делает.

Это страница для вычитки, а не для поиска одной формы. Ничего не свёрнуто и не спрятано: язык лежит подряд, сверху вниз, в том порядке и по тем разделам, которыми размечена таблица ключевых слов самого лексера — их 7. Если нужен работающий пример, который открывается в песочнице нажатием, он в справочнике конструкций: там та же 46 карточка, только с кодом и кнопкой.

Ни одна строка ниже не написана в шаблоне. Формы и все их написания приезжают из таблицы static/js/vendor/flang/lexer.js, разделы — из её собственной разметки, пояснения — из заголовков примеров static/fts/models/ref/. Появилась в языке форма, которой здесь нет, — падает npm test, а не тихо стареет страница.

Все формы языка

По разделам таблицы лексера. В строке — все написания формы: русские и английские равноправны, компилятор принимает любое. Справа — конструкция, которая эту форму объясняет.

документ и модульностьформ 10 · написаний 23

функцииформ 7 · написаний 14

выраженияформ 17 · написаний 38

встроенные формыформ 24 · написаний 49

арифметика и сравненияформ 12 · написаний 41

значения и типыформ 11 · написаний 39

наследие FTSформ 47 · написаний 106

Все конструкции и что они делают

46 конструкций покрывают все 128 форм: каждая форма принадлежит ровно одной конструкции, и это стережёт сборка справочника. Пояснение взято из заголовка примера, который лежит рядом с кодом.

Файл, модуль и типыиз чего состоит программа · конструкций 5

  • Имя для типа: тип «…» это список «…»

    этосписокlist

    Слово «это» даёт имя уже существующему типу — чаще всего списку. Имя типа после этого можно писать вместо «список «Позиция»» везде, где раньше приходилось повторять всю запись целиком.

  • Модуль: имя файла и его экспорт

    модульmoduleэкспортируетexports

    Заголовок называет файл и перечисляет, что он отдаёт наружу. Пространств имён в языке нет: импорт — это слияние объявлений, поэтому имя, вынесенное в «экспортирует», становится общим и обязано быть уникальным.

  • Запись: объект «…» и его поля

    объектструктураobjectstructureзаписьrecord

    Запись — произведение: набор полей с типами. Слова «объект» и «запись» означают здесь одно и то же (в модели FTS то же самое пишут словом «структура»), а имя типа поля — часть контракта и потому точное.

  • Сумма типов: тип «…» и его варианты

    типtypeвариантvariant

    Сумма перечисляет случаи, и у каждого — свои поля. Дальше компилятор следит, чтобы разбор покрывал все варианты: забытый случай — ошибка проверки FLANG_MATCH_NOT_EXHAUSTIVE, а не необработанное значение в проде.

  • Импорт: использует «…» из "…" только «…»

    используетusesтолькоonlyизfrom

    Единственная конструкция языка, которой нужен диск. Пример проверяется командой: `flang check` рядом с файлом читает module.flang, связывает и прогоняет примеры — это и записано в отчёте npm test. «Только» сужает импорт до перечисленных имён: без него модуль вносит все свои, и одного совпадения хватит, чтобы связывание отказало.

    Пример и песочницаref/uses.flang · только в терминале: связывание читает соседний файл (ref/module.flang), а песочница ничего с диска не читает

Функции и примерыобъявление, вызов, тест внутри · конструкций 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

    Надзор объявляется данными, а не кодом: у каждого поднадзорного процесса — своя стратегия, а порог отказов говорит, когда сдаваться и передавать выше. «Порог отказов» — форма из двух слов не для красоты: одиночное «порог» уже живёт именем параметра в стандартной библиотеке, а ключевое слово запрещает имя.