Версию 0.4.6 гейт публикации остановил — печать в Go давала два объявления с одним именем. Дефект починен, и здесь он вместе со всем, что сделано за день.
Монада
монада «Возможно» от «А»
возврат «Обернуть»
соединение «Сплющить»
тотальная функция «Итог со скидкой»
принимает номер: число
возвращает «Возможно» от числа
в монаде «Возможно»
пусть цена равно «Цена позиции» от номер
пусть скидка равно «Скидка по цене» от цена
возврат цена минус скидка
Форма разворачивается внутри разбора: продолжение не строится значением, отображение печатается на месте разбором по вариантам. Поэтому печать во все восемь целей, анализ завершаемости и оба слоя самоприменения получают её даром, а правок в self/parser.flang и self/types.flang — ноль.
Доказывается устройство: тип параметричен, возврат ведёт из «А» в M«А», соединение из M(M«А») в M«А», отображение выводится из устройства типа построением. Проверяется на сетке: три закона — левая единица, правая, ассоциативность связывания, с контрпримером в сообщении.
Отказ стал значением
к числу или беда возвращает «Разобрано» со значением либо «Не разобрано» с кодом и текстом:
сумма 22 по 3 ячейкам; пропущено 2, первая — "abc":
«к числу»: строка "abc" не является числом
Перехват (попытка …) отвергнут по причине из C: прыгать через напечатанный код нечем, longjmp оставил бы арену и счётчик витков в неизвестном состоянии, и это была бы лазейка к перехвату самого предела рекурсии. Тексты отказов совпадают у интерпретатора и всех восьми целей буквально: каждый рантайм зовёт свою к числу и переводит её отказ в значение, второго разбора нет нигде.
Полиморфизм в самом репозитории
self/parser.flang и self/types.flang понимают параметры типа и функции-значения, поэтому библиотека схлопнута: «Возможно» от «А», «Результат» от «Значение» и «Беда». Библиотека высшего порядка переехала из теста в flang/stdlib/higher-order.flang — одна свёртка с функцией-значением даёт сумму, произведение и максимум вместо трёх функций с одинаковым телом.
Второй параметр типа тут же нашёл дефект подстановки в самоприменении, который механизм побайтовой сверки не мог поймать: двухпараметрических типов в языке до сих пор просто не было.
«тотальная» перестала обещать больше, чем доказано
Числа в языке — IEEE-754 double, и выше 2⁵³ вычитание единицы ничего не меняет. Функция, доказанная числовой мерой, на таком входе не завершалась, хотя компилятор объявлял её тотальной.
Теперь понижение вставляет сторожа: мера обязана убыть, иначе отказ.
$ flang run … --args '{"н": 18014398509481988}'
{"error":"тотальная функция «До нуля»: мера не убыла — аргумент 1 вызова
«До нуля» не стал меньше параметра «н». … Отказ здесь честнее зацикливания"}
Цена названа: +52% в собранном C на холостых витках, ровно +10 шагов вычислителя на виток.
Печать в Go
Единственный из восьми бэкендов, который клал конструктор варианта и функцию в одно пространство имён без пометки роли. Именователь молчал, потому что вёл реестр по строке: вариант «Чётное» и функция «Чётное» приходят одной строкой, и он счёл их одним объектом, названным дважды. Добавлен тест, ловящий столкновение имён без тулчейна — на любой машине.
Проверено
На машине со всеми восемью тулчейнами: 1942 теста, 1942 прошли, пропусков ноль. Неподвижная точка самоприменения сошлась: семь напечатанных файлов C совпали побайтово у эталона, flang₁ и flang₂. Архив собран с нуля флагами формулы и запущен.
Установка
brew install digitable-lol/tap/flang