Словарь встроенных форм лежал в девяти местах, и три копии уже разошлись
Тела двадцати встроенных форм языка давно посчитаны на flang. А СЛОВАРЬ этих форм — имена, синонимы, арности, частичность, правило имени вспомогательной функции у генераторов кода — лежал не в одном месте, а в девяти, и каждое место держало свою копию.
Где именно (снято поиском по дереву, а не по памяти):
| Место | Что за копия |
|---|---|
flang/src/builtins.mjs | реализация на JavaScript, 956 строк |
flang/self/interpret.flang | имена, синонимы, арности, склонение слова «аргумент» |
flang/self/types.flang | четыре формы, снимаемые непустотой, перечнем внутри строки |
семь flang/self/emit-*.flang | те же четыре формы и правило суффикса, у каждого свой |
flang/self/parser.flang | тип «Исход числа» и его приписывание программе |
Копии разошлись, и это измерено. У реализации десять синонимов имени формы, а трое из семи генераторов кода — C, C# и Python — несут семь: без код_символа, charCode и к_числу_или_беда. Сегодня от этого не краснеет ни одна проверка, потому что подчёркнутым синонимом форму не пишет ни одна программа корпуса. То есть расхождение не «может случиться», а УЖЕ случилось и живёт молча.
Почему копий стало девять. Ни одна не заводилась по лени. Каждая появлялась потому, что модулю нужны были три-четыре имени, а импортировать ради них весь соседний модуль дорого: связывание тянет модуль целиком. Дешёвый локальный выбор, повторённый девять раз, дал долг, который никто не выбирал.
Что с этим сделано. Заведён flang/self/builtins.flang — одно место, где словарь стоит целиком, — и к нему проверка, сравнивающая его с реализацией на JavaScript побайтово: 8206 имён (двадцать форм, десять синонимов и каждое имя функции и типа 220 разобранных программ дерева), 80 неверных арностей, 476 текстов отказа, 320 имён вспомогательных функций у восьми генераторов кода, 220 программ на приписывание типа исхода. Расхождений ноль.
Чем ограничено. Девять копий от этого НЕ исчезли: заведено десятое место, которое умеет краснеть. Свести к нему остальные — отдельная работа, и она не бесплатна: interpret.flang и семь генераторов кода входят в замыкание точки раскрутки, поэтому всякая правка там требует перепечатки и сверки неподвижной точки. Долг записан долгом, а не закрыт.
Поправка по числу форм. «Двадцать форм» — верный счёт на день замера. Форм теперь двадцать одна: 20 августа 2026 завелась символ по коду (ветка vypusk/simvol-po-kodu), и синонимов стало двенадцать. Замер выше не пересчитан нарочно — он улика того прогона; сегодняшнее число даёт BUILTIN_NAMES.length.
Что случай с двадцать первой формой добавил к самому классу. Девять копий никуда не делись, и каждая потребовала своей правки: словарь в self/builtins.flang, вычислитель, типы, разборщик, отказы и восемь генераторов кода — по три строки в каждом. Красным при этом ни одна копия не стала МОЛЧА: сверка self-builtins.test.mjs назвала расхождение поимённо («форма ли „символ по коду"», «список имён форм»), и десятое место, ради которого заметка и писалась, отработало ровно так, как обещано.
Чем подтверждено. Прогон flang/test/self-builtins.test.mjs, 4,6 секунды, ветка work/vstroennye. Расхождение синонимов найдено не мной — оно записано в flang/self/SPEC.md работой от 17 августа 2026 и здесь только пересчитано.
Связано: minus-zero-is-a-class, a-side-may-already-exist-check-before-writing