22 октября 2026 года компания Modular выпустила Mojo 1.2.0. Язык получил сопоставление с образцом через match и case, более 20 математических функций стали доступны для вычислений на GPU, а время компиляции крупного пакета nn в измерении разработчиков сократилось с 98 до 61 секунды. При переходе на версию 1.2.0 разработчикам также придётся учитывать изменения API строк и хеширования.

Mojo используют для задач, в которых важны скорость выполнения и работа с вычислительными ускорителями. Поэтому в версии 1.2.0 сразу несколько изменений касаются одной проблемы: как писать более понятный код для CPU и GPU, собирать его быстрее и получать предсказуемые численные результаты. Релиз вышел спустя пять недель после Mojo 1.1.0 от 17 сентября.
Сопоставление с образцом match/case упрощает проверку значений в Mojo
В Mojo 1.2.0 появилась конструкция match/case. Она сопоставляет значение с несколькими образцами и выполняет первый подходящий блок. Раньше подобные проверки приходилось выражать через цепочки условий или собственную логику разбора значений.
Например, программа может по-разному обработать HTTP-код ответа: отдельно успешный запрос, перенаправление, отсутствие страницы и серверную ошибку. Документация релиза приводит именно такой сценарий. Ниже — тот же принцип внутри функции main():
def main():
var status_code = 404
match status_code:
case 200:
print("OK")
case 301 | 302:
print("Redirect")
case 404:
print("Not found")
case code if code >= 500:
print("Server error", code)
case _:
print("Unexpected status", status_code)Образцами могут быть числа, кортежи, структуры и другие значения. Вертикальная черта объединяет варианты, а условие после if уточняет совпадение. Символ _ обозначает любой оставшийся случай. В языке появились и связанные формы if case, while case, а также comptime match для проверок во время компиляции.
Это изменение пригодится там, где программа разбирает состояния, результаты вычислений или значения перечислений. Например, структуры стандартной библиотеки, поддерживающие EnumLike, теперь участвуют в сопоставлении через записи вида case .PASS.
Более 20 математических функций Mojo теперь работают на GPU
Разработчики перенесли ряд функций std.math с системной математической библиотеки libm на общую реализацию, написанную на Mojo. Среди них — atan(), tan(), cbrt(), hypot(), log10(), lgamma(), remainder() и функции Бесселя. Теперь соответствующие операции доступны в GPU-коде, где прежде зависимость от системной библиотеки ограничивала их использование.
Разница проявляется в вычислительных ядрах: формулу с такими операциями можно выполнять на ускорителе без необходимости заменять каждую неподдерживаемую функцию специальным вариантом. При этом одинаковая реализация на CPU и GPU упрощает сопоставление результатов, хотя абсолютного побитового совпадения для всех операций разработчики не обещают.
Релиз затрагивает и точность. Для log() в формате float64 заявлена погрешность в пределах одной единицы последнего разряда (ulp) относительно правильно округлённого результата; прежняя реализация в некоторых случаях отклонялась намного сильнее. log1p() тоже получил общую реализацию для CPU и GPU с точностью в пределах одной ulp для float32 и float64.
Ограничения оборудования сохраняются. В частности, вариант log1p() для float64 недоступен на GPU Apple, поскольку эти ускорители не поддерживают вычисления указанного типа. На устройствах, которые обнуляют очень малые числа, возможны особенности обработки субнормальных значений. Поэтому переход к общей математической реализации сам по себе не гарантирует одинаковые младшие биты результатов на всех архитектурах.
Компиляция пакета nn сократилась с 98 до 61 секунды
По данным Modular, время компиляции крупного пакета nn уменьшилось примерно с 98 до 61 секунды. Это показатель конкретного пакета в тесте разработчиков; для произвольной программы такое же ускорение не заявлено.
Отдельная оптимизация касается Linux. Компилятор Mojo теперь использует распределитель памяти jemalloc. На больших файлах с GPU-ядрами это сократило время компиляции примерно на 10–13% за счёт уменьшения расходов на управление памятью в glibc. Два результата относятся к разным измерениям и не должны складываться в общий процент ускорения.
Ускорилась и работа со строками. Методы String.startswith() и String.endswith() теперь зависят по времени от длины проверяемого начала или окончания строки, а не от длины всей строки. Для больших строк это уменьшает объём лишней работы. Разработчики также ускорили выравнивание и повторение строк, однако эти результаты относятся к конкретным операциям и размерам данных.
Изменения StringSpan и хеширования затрагивают существующий код
У версии 1.2.0 есть изменения, которые становятся заметны при сборке старых проектов. Тип StringSpan теперь предоставляет только неизменяемый доступ к байтам строки. Удалены MutStringSpan, MutStringSlice и параметр mut у StringSpan. Код, который изменял байты через такие представления, потребует переработки.
Изменилось и API хеширования. Для последовательности байтов появился отдельный вызов hash_bytes(), принимающий ImmSpan[Byte]; прежняя перегрузка hash() с указателем и длиной объявлена устаревшей. Модуль std.hashlib переименован в std.hash. Методы isspace() для String и StringSpan пока сохраняются, но помечены как устаревшие: новое название is_ascii_whitespace() точнее отражает проверку ASCII-пробелов.
Для кода, определяющего тип GPU на этапе компиляции, тоже изменился интерфейс. Ранее использовавшиеся функции вроде has_nvidia_gpu_accelerator() удалены; теперь проверки выполняются через методы CompilationTarget, включая .is_nvidia_gpu(), .is_amd_gpu() и .is_apple_gpu(). Таким образом, обновление может затронуть одновременно строковые операции, утилиты хеширования и GPU-специфичные участки проекта.
Mojo 1.2.0 устраняет зависания компилятора и ошибки оптимизации
Среди исправлений есть два случая с подробными отчётами на GitHub. В задаче #7164 описывалось падение компилятора при уровнях оптимизации -O2 и -O3: один и тот же пример успешно собирался с -O0 и -O1, но более агрессивная оптимизация приводила к аварийному завершению. В changelog Mojo 1.2.0 исправление этой ошибки подтверждено.
В задаче #7127 вложенные циклы for с булевым флагом могли заставить компилятор работать несколько минут без результата. Автор отчёта отмечал, что вариант с целочисленным счётчиком собирался примерно за секунду. Исправление этой проблемы также включено в версию 1.2.0.
При этом новая конструкция match уже получила отдельное сообщение о потенциальной ошибке: в открытой задаче #7325 обсуждается поведение образцов с условиями, изменяющими проверяемое значение. Это пользовательский отчёт, а не подтверждённый вывод о корректности всех случаев в стабильной версии.
Развитие Mojo 1.x теперь затрагивает синтаксис, GPU и совместимость API
После выпуска Mojo 1.0 с первоначальными гарантиями стабильности отдельных интерфейсов язык продолжает менять стандартную библиотеку. Версия 1.1.0 сосредоточилась, среди прочего, на выводе типов, производительности коллекций и изменениях синтаксиса; версия 1.2.0 добавила сопоставление с образцом, расширила набор математических операций на ускорителях и ускорила отдельные этапы сборки.
Для проектов на Mojo 1.x это создаёт два параллельных эффекта: появляется больше готовых языковых и вычислительных возможностей, а часть прежних API теряет совместимость. Показатели скорости относятся к тестам Modular, а численные результаты на разных GPU по-прежнему зависят от поддерживаемых форматов и свойств конкретного ускорителя.
Источники
- Mojo 1.2.0 — официальный список изменений, 22 октября 2026 года
- Mojo 1.1.0 — официальный список изменений, 17 сентября 2026 года
- GitHub #7164 — падение компилятора на уровнях оптимизации O2/O3
- GitHub #7127 — зависание компилятора при вложенных циклах
- GitHub #7325 — сообщение о потенциальной проблеме в pattern matching