DigitableCourses
Portal settings
Show me around

Local and account-free. No account, no sign-up: whatever you type into the tools stays in this browser's localStorage and never reaches a server.

Our own counter records page opens and finishes: the address leaves, plus one tenth-of-the-text figure. No cookies, no outside trackers, your IP is not stored, Do Not Track is honoured. How to check that

The portal's own repository is not published, so we do not call it open source. What is open:

The portal lives on donations, paid consultations and requested write-ups, and on Workbench sales.

There are no plans to make the courses paid.

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

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

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

Ни одна строка ниже не написана в шаблоне. Формы и все их написания приезжают из таблицы static/js/vendor/flang/lexer.js, разделы — из её собственной разметки, пояснения — из заголовков примеров static/spec/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

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