DigitableCourses
Настройки портала
Показать возможности портала

Локально и без аккаунта. Аккаунта нет, регистрация не нужна: введённое в инструменты остаётся в localStorage браузера и на сервер не уходит.

Свой счётчик считает открытия страниц и дочитывания: уезжает адрес и десятая доля текста. Без cookies и чужих счётчиков, IP не хранится, Do Not Track уважается. Как это проверить

Репозиторий портала не выложен, «открытым кодом» мы его не зовём. Открыто это:

Живёт портал на донатах, платных консультациях и разборах по запросу и покупке Workbench.

Планов делать курсы платными нет.

Библиотеки на языке: flang-tui, flang-ribbon и flang-env

flang-tui, flang-ribbon и flang-env — библиотеки на flang. flang-tui: раскладка терминального экрана, 102 функции, переводится в Go и C. flang-ribbon: арифметика ленты окон, сверена с digitwm на 526 871 входе. flang-env: разбор переменных окружения. Числа сняты 18–19 октября 2026 на flang 0.7.29.

Библиотеки на языке

Три библиотеки, написанные на flang. Все три выросли из настоящих программ портала. Экран и чтение окружения digitdisk были написаны на Go; их переписали на flang, сверили с оригиналом на общем наборе входов, и вышли flang-tui и flang-env. Арифметику ленты окон перенесли из digitwm тем же способом. Там C не убрали, а заменили: десять функций ribbon.c теперь вызывают код, который flang выводит из flang-ribbon (подключён в digitwm подмодулем ribbon-flang/).

Репозиторий Что умеет Строк кода библиотеки Всего строк на flang Переводится в
flang-tui раскладка терминального экрана: полосы, обрезка, укладка, вкладки, прокрутка 3838 6360 Go, C
flang-ribbon арифметика ленты окон: смещения, ширина колонки, высота окна, вставка, панели 1727 2571 C, Go
flang-env разбор значений окружения: глубина цвета, язык, NO_COLOR 807 1210 Go, C

Откуда числа. Замер 18–19 октября 2026, компилятор — готовая сборка flang 0.7.29 для Linux x86_64. Деревья: flang-tui на 7c04e31 (13 сентября), flang-ribbon на d59225b (5 сентября), flang-env на 37120d0 (2 сентября). «Строк кода библиотеки» — модули в flang/; «всего» — все файлы *.flang дерева: git ls-files -z '*.flang' | xargs -0 wc -l. В «всего» входят общая для трёх деревьев проверка лицензий tools/licensing.flang (303 строки), список команд ярлыки.flang, у flang-tui — спецификации в fspec/, у flang-ribbon — программы сверки в tools/. Функции, утверждения и примеры посчитаны flang check --proof --json и flang test по каждому модулю.

Кроме flang, в деревьях есть только короткий запускатель ярлык на sh и у flang-ribbon три скрипта сверки на sh. Ни Go, ни JavaScript, ни Makefile.

flang-tui — экран терминала

Что умеет. Шесть модулей, и граница у всех одна: данные плюс ширина и высота → готовые строки. Ни чтения, ни записи, ни запросов к среде.

Модуль Файл Что делает
«Screen» flang/screen/screen.flang полоса заполнения, обрезка по видимым ячейкам, укладка раздела в высоту, кадр целиком
«Format» flang/format/format.flang размеры, доли, проценты, длительности, счётчики разрядами, прочерк, выравнивание
«Colour» flang/colour/colour.flang истинный цвет, куб xterm-256, шестнадцать базовых
«History» flang/history/history.flang история бегущего графика и строка его знаков
«Scroll» flang/scroll/scroll.flang прокрутка: положение, высота окна, длина содержимого, нажатие → положение
«Tabs» flang/tabs/tabs.flang вкладки: состояние плюс нажатие → состояние

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

Как подключается. Двумя путями.

  • Переводом в Go или C: ./ярлык печать кладёт каждый модуль в out-go/<имя> и out-c/<имя> и собирает обе версии (gofmt, go vet, go build, cc -Werror). Результат встраивается в чужую программу без рантайма flang. Единственная правка выведенного кода — имя пакета Go: у всех модулей оно одно (flangprogram), и sed переписывает его на flang<имя>, чтобы шесть модулей не столкнулись в одной сборке. На 0.7.29 всё собирается, код возврата 0.
  • Пакетом flang: ./ярлык пакеты собирает шесть файлов .flang-package (у каждого модуля свой манифест flang.package). Подключается строкой использует «Screen» из "flang-tui/flang/screen/screen.flang-package"; обещания модуля едут вместе с кодом и доказываются у того, кто подключил.

Чем проверяется. ./ярлык проверка — flang check и flang test по каждому модулю. На 0.7.29:

Функций Тотальных Утверждений доказано на сетке значений Примеров
Шесть модулей 102 102 71 23 48 613 из 613

«Доказано» — для всех входов. «На сетке значений» — постусловие посчитано на значениях из примеров; это не доказательство, и отчёт так и пишет.

Что на 0.7.29 краснеет. Два ярлыка библиотеки написаны под прежний компилятор и на 0.7.29 падают:

  • ./ярлык ведомость выходит кодом 1: начиная с 0.7.29 flang check --proof отвечает кодом 3, если часть утверждений держится только на сетке, а здесь таких 48;
  • ./ярлык спеки выходит кодом 3: с 0.7.21 flang io не запускает план, у которого не всё доказано, без ключа --на-веру (125 утверждений: 75 доказано, 50 на сетке).

Сам код библиотеки от этого не меняется: проверка и примеры проходят.

Сверка с оригиналом. Её делали дважды, 2 и 3 сентября 2026, на flang 0.6.2: 494 467 входов против digitdisk 0.5.0 и 1 944 268 входов против digitdisk 0.8.0, расхождений 0. Программа сверки на Go после этого удалена из дерева, а ответы оригинала на граничных входах перенесены в модули примерами — это те же 613 примеров, которые проходят на 0.7.29. Если поменяется digitdisk, примеры этого не заметят.

flang-ribbon — лента окон

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

Модуль Файл Что решает
«Viewport» flang/viewport.flang смещение по ленте и вниз по стопке; поправка смещения после смены размера экрана
«Geometry» flang/geometry.flang ширина колонки от доли и от пресета, высота окна в стопке, деление нацело по правилам C99
«Placement» flang/placement.flang куда встаёт новое окно, кто получает фокус после закрытия
«Strut» flang/strut.flang пересекаются ли панель и область, сколько панель забирает от края, что остаётся двум панелям напротив друг друга
«Ribbon» flang/ribbon.flang лента как значение: колонки, фокус, два смещения; вставка окна как функция «лента → лента»

Оригинал — ribbon.c из digitwm, десять функций ribbon_policy_* на закреплённом коммите bfd5d85. Строк C из digitwm в дереве нет: арифметика записана на flang заново.

Как подключается. Переводом: flang emit flang/geometry.flang --target c --out out-c/geometry, так же в Go. В digitwm это уже работает: в ribbon.c десять функций ribbon_policy_* — тонкие обёртки над выведенным C из подмодуля ribbon-flang/ (он закреплён на 66d3493, на два коммита раньше main библиотеки). Таблицу долей ширины, которую оригинал читал из глобальной Conf, функция получает аргументом.

Чем проверяется. На 0.7.29:

Функций Тотальных Утверждений доказано на сетке значений Примеров
Пять модулей 60 60 31 6 25 199 из 199

./ярлык проверка и ./ярлык сетка (оба обещания ленты пересчитаны на 896 лентах) проходят. ./ярлык ведомость на 0.7.29 выходит кодом 1 по той же причине, что у flang-tui: 25 утверждений держатся на сетке.

Сверка с оригиналом — команда, и она повторена на 0.7.29. ./ярлык сверка (tools/compare.sh) клонирует digitwm на закреплённом коммите и сверяет sha256 ribbon.c, вырезает десять функций в отдельный объектный файл (у него ровно одно неопределённое имя — Conf), выводит четыре модуля в C и в Go и гоняет все три реализации на 526 871 входе. Прогон 19 октября 2026:

$ ./ярлык сверка
…
сверено входов: 526871
расхождений:    0
теорема пары («Пара вместе», счётчика в эталоне нет): проверена на 4536 входах, не сработала 0 раз
потоки ответов совпали побайтно: строк 526871, байт 14458160 (cmp)
…
напечатанное в Go совпало с эталоном побайтно: строк 526871 (cmp)

Ответы оригинала C, выведенного C и выведенного Go совпали байт в байт.

У одной функции пары в оригинале нет: «Пара вместе» складывает обе доли двух панелей и обещает, что вместе они не займут больше, чем есть в области. Доказательства у этого обещания нет; в выведенном коде оно проверяется при работе, и сверка считает, сколько раз оно сработало.

Отрицательный контроль. ./ярлык наоборот портит копию дерева и требует, чтобы каждая проверка покраснела: подменённый ответ примера, строка вместо числа, ложное постусловие, сломанный модуль (для check --proof и для emit), подложенные чужая лицензия, чужой язык и рукописный C, перевранная арифметика для сверки. На 0.7.29 все эти порчи ловятся. Не сработал один контроль: ужесточённое обещание ленты краснеет, но не тем постусловием, которого ждёт скрипт, и он выходит кодом 1. Сверку вставки против живого cwm не запускали: для неё нужен собранный оконный менеджер.

Находка при переносе. Первый прогон сверки дал 606 расхождений из 526 871, все на ширине колонки. Ошибалась не арифметика, а постусловие: в flang, как в IEEE-754, есть +0 и −0, и (0 − 0) × −20 даёт −0. Постусловие «частное и остаток восстанавливают делимое» без нормализации отвечало отказом там, где оригинал возвращал ноль. Исправляет плюс 0 (приём из flang/stdlib/numbers.flang); случай записан примером в «Ширине колонки».

Что осталось в C. ribbon.c на текущем digitwm (b8e5d1b) — 1640 строк. Кроме десяти обёрток там обход списков и память (TAILQ_*, malloc, free) и вызовы оконной системы. Этого в библиотеке нет и не будет: библиотека, которая знает про client_show, становится половиной оконного менеджера.

flang-env — окружение

Что умеет. Два слоя.

Слой 1 — модуль «Env», flang/env.flang: чистые тотальные функции. Программа передаёт строки, библиотека решает: сколько цвета терпит терминал (NO_COLOR, TERM, COLORTERM), годен ли он под экран, на каком языке говорить, какими знаками писать числа. Переводится в Go и C и встраивается в чужую программу.

Слой 2 — план «Прочитать окружение», flang/read-env.flang: читает шесть переменных сам (через printenv) и отдаёт ответ слоя 1. Исполняет его flang io.

Переменная — это вариант, а не строка: вариант «Задано» с значение равным … против вариант «Не задано». Пустая строка и отсутствие переменной — разные вещи, и тип это различает. Так сделано ради NO_COLOR, который действует самим своим наличием.

Как подключается. Слой 1 — переводом в Go или C. Слой 2 на 0.7.29 переводится во все цели (go, c, rust, js — код 0), но выведенная программа план не исполняет:

$ flang emit flang/read-env.flang --target c --out env-c && make -C env-c
$ ./env-c/flang_cli --plan 'Прочитать окружение'
{"error":"… исполните план двоичным: flang io <файл.flang>: Запустить процесс","code":"FLANG_IO_NOT_WIRED"}

Поэтому путей два: кому нужно, чтобы окружение читала сама библиотека, зовёт flang io; кому нужно, чтобы разбор жил внутри его программы, берёт переведённый модуль «Env» и передаёт строки сам.

С 0.7.21 flang io не запускает план, у которого не все утверждения доказаны: у read-env одно из двух держится на сетке, и запуск идёт по ключу --на-веру:

$ flang io flang/read-env.flang --на-веру
на веру: доказанность не считалась — запуск по ключу --на-веру
{"plan":"Прочитать окружение","result":"цвет: 256; язык: ru; область: RU; дробный: «,»; разрядный: « »", …}

Чем проверяется. На 0.7.29:

Функций Тотальных Утверждений доказано на сетке значений Примеров
«Env», слой 1 25 25 9 4 5 103 из 103
«ReadEnv», слой 2 7 7 2 1 1 117 из 117

Четыре ярлыка библиотеки написаны под прежний компилятор и на 0.7.29 падают — каждый потому, что язык изменился, а не код библиотеки:

  • ./ярлык ведомость — код 3: часть утверждений держится на сетке;
  • ./ярлык отказ ждёт, что для плана отчёт о доказательствах не печатается (код 2), а 0.7.29 его печатает (код 3);
  • ./ярлык граница ждёт, что Go, C и Rust откажутся переводить план, а 0.7.29 переводит (код 0);
  • ./ярлык план — flang io без --на-веру отказывается запускать план.

./ярлык проверка и ./ярлык лицензии проходят.

Сверка с digitdisk — 402 входа, 0 расхождений — была разовой (2 сентября, flang 0.6.2); 41 из 103 примеров слоя 1 — ответы оригинала на закреплённом коммите.

Цена flang io. Медиана десяти запусков, та же машина:

Что Время
flang io flang/read-env.flang --на-веру 0,97 с
flang check flang/read-env.flang 1,16 с
printenv TERM 3 мс

Почти всё время уходит на проверку программы перед запуском, а не на чтение переменных. Поэтому flang io годится для старта, установки и CI, но не для горячего цикла; там место переведённому слою 1.

Общее у всех трёх: make нет

Точка входа — ./ярлык, короткий скрипт на sh. Списка команд в нём нет: он спрашивает строку команды у программы ярлыки.flang и запускает её. Сам список — программа на flang: с типами, примерами и обещанием о числе команд. Список модулей нигде не записан — команды берут flang/*.flang, поэтому новый модуль не может молча выпасть из проверки.

Все три — под BSD-2-Clause, написаны с нуля. Поведение сверено с оригиналами по их открытому исходнику: flang-tui и flang-env — с digitdisk, flang-ribbon — с digitwm.

См. также

  • Описание языка — что за язык, два класса программ, перевод в другие языки
  • Справочник конструкций — карточка с примером на каждую форму
  • Практикум — восемь ступеней, вердикт выносит исполнение
  • digitdisk — программа, из которой выросли flang-tui и flang-env
  • digitwm — программа, из которой перенесена арифметика flang-ribbon

Нашли неточность? Выделите фрагмент текста — рядом появится жучок.

Нужен разбор именно вашей ситуации?

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

Доска запросов
Дальше