От JavaScript остаётся только цель печати, второе мнение отменено вместе с ловушкой Томпсона
19 августа 2026 владелец отменил решение «реализация на JavaScript уходит из продукта, но остаётся в проверках вторым мнением» (§5 docs/javascript-removal.md) и распорядился удалить вторую реализацию целиком — и из продукта, и из проверок. Остаётся ровно одно: цель печати --target js (генератор кода flang/src/emit/js.mjs, 3 353 строки, и её рантайм), чтобы flang можно было встроить в чужую программу на JavaScript.
Поправка по размеру. Здесь стояло «3 198 строк» — верное число на день записи, потом «3 219» и «3 332» на двух разных деревьях. Файл рос вместе с языком: последняя прибавка — помощник $b_simvol_po_kodu у встроенной формы «символ по коду». На собранном дереве замерено заново, wc -l: 3 353. Число заменено на сегодняшнее, потому что оно тут не улика замера, а описание того, что остаётся в продукте; улика замера — в остальных числах заметки, и они не тронуты.
Чем это отличается от прежнего решения. Прежнее считало сверку двух порознь написанных реализаций несменяемой ценностью и оставляло свидетеля замороженным. Новое признаёт: свидетель, который нельзя удалить, — это второй компилятор, который приходится вечно догонять, а догонять его перестают молча.
Что удалено первым и почему именно это. Семь модулей проверки законов (commutative, distributive, idempotent, iso, monoid, monotone, partialorder), 1 403 строки. Они уже вышли из рабочего пути раньше и держались ТОЛЬКО ролью второго мнения — то есть удаление ничего не ломает по существу, а только стирает мнение. Вместе с предметом ушли 207 проверок, чьим предметом был свидетель: девять файлов целиком (150 проверок) и побайтовые половины двух файлов сверки (self-laws 24 из 34, self-svoystva 33 из 43).
Сохранённое отделено от удалённого руками, а не файлами. В обоих файлах сверки остались 20 проверок стороны на flang: разбор, связывание, типы, завершаемость, отсутствие обычных функций, сходимость примеров, пределы сеток. Приём: сверка «предел у эталона тот же, что у свидетеля» перенацелена на копию числа в src/self.mjs, хозяином которой остался слой на flang. Так проверка переживает удаление предмета, не превратившись в сравнение слоя с самим собой.
Что остаётся из JavaScript и почему это НЕ второе мнение. Два остатка легко спутать со свидетелем, и различие надо держать:
- 295 строк представления значения в
builtins.mjs— невыразимо языком: у каждой из восьми целей печати своё представление значения внутри вычислителя; reachable.mjs, 248 строк — невыразимо по цене: сторона на flang даёт тот же ответ, но в 181 раз медленнее на горячем пути (143 мс → 25 905 мс на компиляторе), а зовётся при каждой печати во все восемь целей.
Ни у того ни у другого мнения нет вовсе: их не спрашивают «а что скажешь ты», их спрашивают «как это исполнить». Второе мнение — это когда двое отвечают на один вопрос и ответы сравнивают; здесь второго ответчика нет.
Отрицательный результат, который надо записать: цена не заменяется ничем равным. Свидетель ловил односторонние правки, и ловил не гипотетически — за 18 августа так нашлись отставание печати у 7 целей из 8, командная строка без lock, завершаемость без постусловий. После удаления остаются три вещи, и ни одна не равна ему:
- корпус порч — испорченный слой на flang обязан краснеть. Ловит порчу, НЕ ловит одностороннюю правку: правка не порча, она зелёная с обеих сторон;
- встречная сверка двоичного из
bootstrap/— ловит расхождение «исходник против собранного», не ловит устойчивую ошибку в самом исходнике; - запись ответов, снятая до удаления — слабее тем, что её можно переснять и что она не растёт вместе с языком.
Ловушка Кена Томпсона после удаления не закрыта ничем. Это не довод против решения — решение принято с названной ценой, — но записать цену обязательно, иначе через месяц её сочтут закрытой.
Чем подтверждено. Ветка work/udalenie-js поверх ствола e56d33d7, коммиты 3a6c59f2 и 12efbdef. Перепись рабочего пути (flang/test/rabochiy-put.test.mjs) до и после: 29 файлов, 36 550 строк — не изменилась, потому что удалённые модули из пути вышли раньше. После удаления зелены: self-laws + self-svoystva 20 из 20, dead-code + code-guard 21 из 21.
Порядок исправлен на следующем ярусе, и это главный вывод дня. На ярусе законов запись ответов не снималась — оттого 36 порч и пропали безвозвратно. На ярусе оракулов сделано наоборот: сперва снята запись (284 программы корпуса, 4 свидетеля, 1 136 ответов, из них непустых на 7 программах, отпечаток sha256 всего потока заморожен в flang/test/fixtures/zapis-oracula.json), и только после этого можно удалять. Правило, которое стоит держать как класс: перед удалением свидетеля снимай запись его ответов; после удаления снимать уже не с чего. Запись слабее свидетеля тремя названными способами (только корпус дня съёмки; не растёт с языком; можно переснять), но одно она держит точно — одностороннюю правку стороны на flang, упирающуюся в замороженное число.
Чем ограничено. 36 порч (снять правку и посмотреть, что покраснеет), краснивших на испорченном слое flang, ушли вместе со сверкой: они сравнивали два оракула, и без второго сравнивать не с чем. Заменять их надо записью ответов, снятой ДО удаления следующего яруса, — и это надо сделать раньше следующего удаления, а не после.
Связано: four-pieces-of-javascript, removed-from-the-decision-and-removed-from-the-load-are-two-events, checks-that-stopped-comparing