- разложение строки
- Нет встроенной формы «символы строки» и нет образцов для строк: «пусто» и «голова и хвост» работают только со списком. Любой посимвольный проход — обычная функция. Это самая дорогая из недостач: она одна делает нетотальными задачи 13, 14, 20, 125.
- убывание по мере
- Анализ завершаемости знает только структурное убывание. Рекурсия «n минус 1», Евклид, двоичный поиск по границам — всё это FLANG_NOT_TOTAL, хотя завершается очевидно. Обход есть (список-топливо), но он засоряет сигнатуру.
- ассоциативный массив
- Нет ни словаря, ни множества. Каждая задача «посчитай, сколько раз встретилось» превращается из O(n) в O(n²): 1, 136, 169, 217, 49.
- массив с индексным доступом
- Список читается только с головы; «Элемент по номеру» пишется рекурсией и стоит O(n). Кучи, таблицы динамики и двумерные сетки на этом ломаются.
- сравнение строк
- types.mjs разрешает «больше»/«меньше» для строк, а interpret.mjs на них бросает FLANG_TYPE. Это расхождение слоёв: программа проходит проверку и падает при запуске. Сортировка строк невыразима.
- логические операции
- Нет «и», «или», «не» для признаков. Конъюнкция пишется вложенными «если», отрицание — сравнением «равен нет». Читается заметно хуже написанного условия.
- параметрический полиморфизм
- «Обратить» для списка числа и для списка строки — две разные функции с одинаковым телом. Опциональное значение приходится заводить отдельно под каждый тип, а имена вариантов обязаны быть уникальны в модуле.
- модульность
- Заголовок «модуль … использует …» разбирается, но связывания между файлами нет: каждое решение переписывает нужные ему «Приписать в начало» и «Соединить списки» заново. Стандартной библиотекой нельзя воспользоваться из решения.
- значение варианта в примере
- parseLiteralValue сворачивает конструктор варианта в запись из его полей и теряет имя варианта. Поэтому функция, принимающая или возвращающая сумму типов, примера иметь не может — приходится обкладывать её скалярными обёртками.
- структурное сравнение в примерах
- runExamples (compat.mjs) сравнивает результат с ожидаемым через Object.is, поэтому любой пример, возвращающий список или запись, считается провалившимся, даже когда значения совпадают поэлементно. Команда «flang test» на таких файлах не работает; тесты в flang/test сравнивают структурно (valuesEqual) и проходят.
- встроенная форма «символ»
- Парсер и builtins.mjs передают «символ N в текст» как (число, строка), а types.mjs ждёт (строка, число). Любое использование формы «символ» не проходит check; вместо неё приходится писать «подстрока текст с N по N».
- встроенная форма «пусто»
- В позиции выражения слово «пусто» всегда читается как литерал пустого списка, поэтому до одноимённой встроенной формы (проверка «список или строка пусты») из исходника не добраться. Пишется «(длина x) равен 0».
- списочная форма «соединить»
- builtins.mjs умеет «соединить список с разделителем», но поверхностный синтаксис «соединить X с Y» всегда даёт склейку двух строк. Соединение списка строк написано в stdlib заново.
- вызов функции без аргументов
- Применение записывается только как «Имя» от аргумента, поэтому функцию с пустым списком параметров вызвать нечем. Константы приходится делать функциями от неиспользуемого аргумента или встраивать выражением.
- псевдоним типа
- «тип «X» это список числа» разбирается в узел alias, но types.mjs раскладывает объявления на суммы и записи, и alias становится записью без полей. Пользоваться псевдонимами нельзя.
- обработка ошибок
- Отказ встроенной формы («к числу» от «abc», «голова» от пустого списка) прекращает вычисление целиком и не перехватывается. Проверять пригодность аргумента приходится заранее, а выразить эту проверку удаётся не всегда.