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

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

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

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

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

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

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

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

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

Язык, на котором нечего написать, кроме примеров из справочника, языком не работает. Здесь — три библиотеки, которые написаны на flang целиком: ни Go, ни питона, ни JavaScript, ни Makefile в деревьях нет вовсе, и это не обещание в README, а проверка в их конвейерах (tools/licensing.flang плюс нарочно тупой сторож над git ls-files).

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

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

Числа flang-tui и flang-env сняты с деревьев 2 сентября 2026: flang-tui на 617fe0d, flang-env на 37120d0, компилятор — 0.6.2. Числа flang-ribbon — тем же способом и в тот же день, на 66d3493. Команда, которая их печатает: git ls-files '*.flang' | xargs wc -l. Во все три суммы входит общая обвязка — лицензионный сторож (303 строки, дословно один и тот же файл во всех трёх деревьях) и список команд ярлыки.flang (свой в каждом дереве, длина разная — считает число собственных ярлыков); собственно библиотечного кода в flang/3122 строки в flang-tui, 1035 в flang-ribbon и 807 в flang-env.

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

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

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

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

Как подключается. Не пакетом, а печатью: ./ярлык печать кладёт каждый модуль в свой каталог out-go/<имя> и out-c/<имя>, и напечатанное уезжает внутрь чужого двоичного файла — без рантайма, без Node, без интерпретатора. Одна правка напечатанного делается sed, а не рукой: у всех целей печати имя модуля Go одно (flangprogram), и после печати оно переписывается на flang<имя> — иначе шесть библиотек в одной сборке столкнулись бы именами.

Чем проверяется. ./ярлык проверка — это flang check и flang test. Ведомость — вывод flang check --proof, и слова в ней не смешиваются:

Функций Все тотальны Утверждений доказано сетка объявлено, не доказано Примеров
Шесть модулей 81 81 из 81 67 12 46 9 508

«Доказано» — про все входы; «сетка N» — посчитано на N значениях автора, это не доказательство; «объявлено, не доказано» — считает рантайм на тех входах, что придут. Из 67 утверждений доказаны 12.

Сверка с оригиналом кончилась, и это сказано вслух. 494 467 входов против живого Go-эталона, 0 расхождений — но гонялась она руками и в конвейере не стояла ни разу. Сверщик убран из дерева вместе с последним Go; ответы эталона перенесены в модули 362 примерами, которые идут на каждый толчок. 0,07 % сетки, зато всегда. Пример закрепляет значение и не заметит, если изменится digitdisk, — обратного здесь никто не утверждает.

Цена обещаний названа числом. Кадр 200×50, go test -bench, три прогона, 1 сентября 2026: напечатанный в Go код с постусловиями — 55,9 мс на кадр, без них — 10,1 мс, ручной Go — 0,13 мс. То есть обещания стоят 5,3 раза (18 кадров в секунду против 99). Отсюда правило: утверждение пишется, но рабочая сборка печатается без него — проверка живёт в flang check и flang test, а не в горячем цикле.

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

Что держит. Четыре модуля, вопрос тот же, что у flang-tui: данные плюс размеры экрана → куда что встаёт. Ни X11, ни событийного цикла, ни чтения конфига.

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

Эталон — digitwm, файл ribbon.c, десять функций ribbon_policy_*, коммит bfd5d85 (пришпилен нарочно: сверять против уехавшего эталона нельзя). Перенос — не копирование текста: ни одной строки C из digitwm в этом дереве нет, вся арифметика заново записана на flang.

Как подключается. Печатью, не пакетом: flang emit flang/geometry.flang --target c --out out-c/geometry, и так же в Go. Девять функций эталона — прямая замена один в один; десятая, ширина колонки, в оригинале читает глобальный Conf.ribbonwidth[preset] — здесь таблицу долей передают доводом, а хозяину остаётся обёртка в одну функцию. Так это уже устроено и на практике (проверено 3 сентября 2026): в дереве digitwm ribbon.c держит десять именно таких тонких обёрток, а саму арифметику приносит ribbon-flang/ — пришпиленный субмодуль flang-ribbon с уже собранным C (ribbon-flang/out-c/).

Чем проверяется. ./ярлык проверкаflang check и flang test. Ведомость — вывод flang check --proof:

Функций Все тотальны Утверждений доказано сеткой Примеров
Четыре модуля 21 21 из 21 27 6 21 136

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

Сверка с оригиналом — команда, а не архив. У flang-tui и flang-env сверщик снят из дерева вместе с последним Go; здесь digitwm остаётся живым хозяином, и tools/compare.sh остаётся в дереве. Он клонирует digitwm на пришпиленном коммите и сверяет sha256 ribbon.c (уехавший эталон не сверяют), вырезает десять функций тем же приёмом, которым это делает сам digitwm (tools/no-x-build.sh), требует ровно один неопределённый символ в объектнике — Conf, — и на 526 871 входе сравнивает три потока ответов побайтно: эталон на C, напечатанное в C, напечатанное в Go. Результат прогона 2 сентября 2026: 0 расхождений, 526 871 строка, 14 458 160 байт, сверено cmp.

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

Негативный контроль ловит и собственную ловушку. ./ярлык наоборот ломает копию дерева семью способами и требует красного каждый раз — включая проверку, что flang check --proof "$m" | tail -8 без pipefail возвращает код tail, а не проверки. Именно эта ловушка полгода держала «зелёную» ведомость доказательств в двух соседних репозиториях.

Что осталось у хозяина. ribbon.c — 1542 строки, перенесено 297 (строки 78–374, десять функций с комментариями). Остальные 1245 строк — сорок функций в двух группах: обход списков и память (TAILQ_*, malloc, free — 65 строк на них одних) и связь с оконной системой (одиннадцать имён из wsi.h по nm -u ribbon.o, а не по grep: ribbon_client_insert находится грепом и как часть client_insert, что даёт двадцать вместо одиннадцати). Ни одной из этих 1245 строк в flang-ribbon нет: библиотека, которая знает про client_show, перестаёт быть библиотекой и становится половиной оконного менеджера.

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

Что держит. Два слоя, и граница между ними — не вкус, а свойство языка.

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

Слой 2 — план, который читает окружение сам. Исполняет его flang io — тот же двоичный компилятор, что собирается одним cc. JavaScript при исполнении не участвует ни байтом.

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

Как подключается — и где отказывает. Слой 1 печатается куда угодно; слой 2 — нет, и об этом говорит сам компилятор:

$ flang emit flang/read-env.flang --target go --out /tmp/x
flang emit: печать отказала — FLANG_PLAN_UNSUPPORTED: цель «go» не умеет
печатать объявление «план».

Коды возврата: go, c, rust уходят 1; js, который план печатает, — 3 («напечатано, но проверено не всё»). Все четыре сторожит ./ярлык граница, и он стоит в конвейере. Отсюда два пути, и оба настоящие: кому нужно, чтобы окружение читала сама библиотека, — зовёт flang io; кому нужно, чтобы разбор жил внутри его двоичного файла, — берёт напечатанный модуль «Env» и передаёт строки сам.

Чем проверяется. Ведомость слоя 1: 25 функций, все тотальны, 9 утверждений (4 доказаны, 5 — сеткой), 103 примера. Сверка с digitdisk — 402 входа, 0 расхождений — тоже кончилась и тоже заменена примерами: 41 из 103 примеров слоя 1 суть ответы эталона, посчитанные им самим на закреплённом коммите, а не набранные руками.

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

Цена flang io названа числом, по 10–50 холодных прогонов на строку:

Что На прогон
flang io flang/read-env.flang (шесть переменных, план целиком) 1,08 с
flang check той же программы 1,17 с
printenv TERM 4,0 мс
Программа на Go, читающая те же шесть переменных 24 мс

Вывод числом, а не мнением: звать flang io из горячего цикла нельзя — это в 270 раз дороже одного printenv. Почти вся цена не в чтении, а в проверке: flang io перед исполнением судит программу тем же путём, что flang check, и это видно по второй строке. Место flang io — старт, установка, CI, разовая справка; место напечатанного слоя 1 — всё остальное.

Чего не сверяли — сказано тоже. Разбор языка и правила чисел сверять не с чем: fmt в Go к языку нечувствителен. Таблица языков (36 языков с запятой в дробной части, 20 из них с пробелом в разрядах) набрана по glibc и стоит в ведомости как «объявлено, не доказано».

Общее у всех троих: make здесь нет

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

Одно, что Makefile нёс, выброшено нарочно — список имён модулей. Он мог разойтись с деревом молча: седьмой модуль просто не проверялся бы и не печатался, а всё оставалось бы зелёным. Вместо списка стоит flang/*.flang; расходиться нечему.

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

См. также

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

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

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

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

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