В своё время посты на
Хабре и
Reddit о
статически типизированном скриптовом языке
Umka вызвали весьма активную дискуссию.
Прошедшие полтора месяца позволили мне избавиться от некоторых
заблуждений, развить язык и дать чуть более вразумительные ответы
на вопросы публики. Как и следовало ожидать, наиболее серьёзное
испытание выпало на долю самой концепции статической типизации. Она
осталась в основе языка, но потребовала компромиссов в частности,
для корректной сборки мусора.
Появились первые замеры быстродействия интерпретатора в сравнении с
Wren и Python их результаты внушают оптимизм. Наконец, родился
более реалистичный пример использования Umka по его основному
назначению, т. е. как встраиваемого языка.
Информация о типах во время исполнения программы (RTTI).
Проект начинался с радикального отказа от хранения типов данных при
исполнении программы. Вся информация о типах терялась после
компиляции в байт-код виртуальной машины. В принципе, статическая
типизация позволяет это сделать, а заодно избавляет от странных
трюков вроде
упаковки данных в NaN, к
которой, например, прибегают создатели JavaScript и Wren ради
увеличения быстродействия. Однако обнаружились два случая, в
которых пришлось использовать RTTI:
- Приведение интерфейсного типа данных к конкретному прямой
аналог утверждения типа (type assertion) в Go, а также, отчасти,
оператора
dynamic_cast
в C++. Оно требуется и при
сборке мусора, содержащегося в данных, приведённых к интерфейсному
типу.
- Сборка мусора, связанного с динамическими структурами данных
вроде списков и деревьев.
Быстродействие. Изначально Umka никак не предназначался для
установления рекордов быстродействия. Безразличие публики к
медлительности Python наводило на мысль, что скорость вовсе не то
качество, которого в первую очередь ожидают от скриптового языка.
Однако успех LuaJIT и активная реклама Wren заставили задуматься.
После этого меня уже не удивляло, что и ранние публикации про Umka
вызвали вопросы о быстродействии, хотя мне по-прежнему интересно,
от кого в первую очередь исходит спрос на скорость. От
разработчиков игр?
Пока полный набор тестов не готов, я могу поделиться лишь
предварительными результатами замеров. В численных задачах
(например, задаче многих тел) Umka надёжно опережает Python, а если
в задаче активно используется цикл
for
, то Umka даёт
выигрыш даже по сравнению с Wren, который позиционируется автором
чуть ли не как самый быстрый скриптовый язык после LuaJIT.
Наглядным примером служит
перемножение больших
матриц:
Умножение матриц 400 x 400 (AMD A4-3300M @ 1.9 GHz, Windows
7)
Очевидно, в пользу Umka здесь сыграла поддержка традиционных
статических массивов и более низкоуровневая организация цикла
for
, не содержащая вызовов методов.
Задачи с интенсивной сборкой мусора (например, создание и обход
двоичных деревьев) вызывают много сомнений по поводу
эквивалентности сравниваемых алгоритмов. Например, известная
реализация двоичных деревьев на Python
возвращает
содержимое узлов россыпью и выглядит так, будто в принципе
допускает размещение всего дерева на стеке вообще без использования
кучи и сборки мусора. Однако она, по-видимому, требует динамической
типизации и не может быть точно воспроизведена на Umka. Если же
потребовать
возвращать узлы в виде структур,
как в Umka (а за неимением структур приходится требовать объекты),
то быстродействие Python сразу же падает в 3-4 раза.
Вариант на Umka вдвое отстаёт от первой реализации и
вдвое опережает вторую. Какое сравнение корректнее не знаю.
Взаимодействие с внешним кодом. Коль скоро язык
рассматривается как встраиваемый, понадобился более или менее
реалистичный
пример взаимодействия кода на C и
Umka. В нём средствами игровой библиотеки
raylib формируется трёхмерная сцена, а наполнение
сцены определяется внешним скриптом на Umka. В примере можно найти
и вызов функций Umka из кода на C, и вызов функций C из Umka.
Статическая типизация языка Umka позволила естественным образом
формировать на нём структуры данных, непосредственно воспринимаемые
библиотекой raylib.
Пример трёхмерной сцены, содержимое которой задаётся скриптом на
Umka
Обобщённые типы и функции (generics). Как только читатель
улавливает сходство Umka с Go, пускай даже синтаксическое следует
вопрос о поддержке generic'ов. Работа в этом направлении пока не
вышла из стадии обзора подходов. Конечно, хотелось бы
воспользоваться предложениями разработчиков Go, однако
сосуществование в их головах интерфейсов и контрактов всегда
отпугивало, как странное дублирование понятий. К удивлению и
радости, в только что вышедшей
новой редакции
черновика контракты исчезли по тем же причинам, о которых
размышлял и я. Пока generic'ов в Umka нет, остаётся пользоваться,
как и в Go, пустыми интерфейсами
interface{}
.
Документация. Полная спецификация Umka ещё в работе, но уже
написана
грамматика и расширен
обзорный тур по основным возможностям языка.