Лиспоподобный язык размером с Lua и мощью Python
Представьте, что вам нужно добавить скриптовый движок в проект на C или написать быструю автоматизацию для системы. Обычно выбор падает на Lua из-за её легкости или на Python из-за обилия стандартных функций. Но есть вариант, который пытается усидеть на двух стульях сразу — это Janet.
Janet — это динамический язык программирования и байт-код виртуальная машина. По духу это Lisp, но с современным подходом к структурам данных и встроенным возможностям. Проект назван в честь персонажа из сериала «В лучшем мире», и это довольно точно передает суть: язык старается быть максимально полезным и всезнающим, оставаясь при этом компактным.
Почему на него стоит взглянуть
Если вы когда-нибудь пробовали внедрять Lua в C-код, то знаете, насколько это удобно. Janet предлагает похожий опыт: весь интерпретатор можно собрать в один файл janet.c и просто закинуть в свой проект. При этом из коробки вы получаете гораздо больше, чем в «чистой» Lua.
В стандартной библиотеке Janet более 600 функций и макросов. Тут и работа с сокетами, и многопоточность, и манипуляции с файловой системой. Вам не придется искать сторонние библиотеки, чтобы просто поднять TCP-сервер или распарсить JSON.
Что внутри
Janet — это не просто очередной клон Scheme или Clojure. У него есть свои характерные черты, которые делают разработку приятнее.
Например, вместо привычных регулярных выражений Janet использует PEG (Parsing Expression Grammars). Это более мощный и читаемый способ описывать грамматики для парсинга текста. Если вам хоть раз приходилось поддерживать регулярку длиной в три строки, вы оцените этот подход.
Вот как выглядит простой TCP эхо-сервер:
(defn handler
[stream]
(defer (:close stream)
(def b @"")
(print "Connection!")
(while (:read stream 1024 b)
(:write stream b)
(buffer/clear b))))
(net/server "127.0.0.1" "8000" handler)
Обратите внимание на синтаксис: это типичный Lisp, но с объектно-ориентированными нотками вроде :read или :write. Это делает код чище и понятнее для тех, кто привык к мейнстримным языкам.
Ключевые фишки
- Легкое встраивание. Весь проект компилируется в одну амальгаму (огромный .c файл). Это мечта для системных программистов.
- Event Loop и Green Threads. В Janet встроена событийная петля (как в Node.js), которая работает через epoll на Linux или IOCP на Windows. Есть поддержка «зеленых потоков» для эффективного ввода-вывода.
- FFI без боли. Если вам нужно дернуть функцию из системной библиотеки, не обязательно писать обертки на C.
Пример вызова системного окна в Windows через FFI:
(ffi/context "user32.dll")
(ffi/defbind MessageBoxA :int [w :ptr text :string cap :string typ :int])
(MessageBoxA nil "Hello from Janet!" "Test" 0)
Как это работает на практике
Janet отлично подходит для системного скриптинга — там, где Bash уже не справляется со сложностью, а Python кажется слишком тяжеловесным. Его часто используют для создания игровых движков, инструментов автоматизации или как встроенный язык конфигурации с логикой.
В языке есть четкое разделение на мутабельные и иммутабельные структуры данных. Массивы (array) можно менять, а кортежи (tuple) — нет. То же самое с таблицами и структурами. Это помогает избегать типичных ошибок при работе с состоянием в многопоточной среде.
Чего ждать от производительности
Janet — это интерпретируемый язык. По скорости он сопоставим с Lua или Python без JIT-компиляции. Для критически важных участков кода автор рекомендует использовать расширения на C. Но благодаря тому, что все значения упакованы в 8-байтовое представление и эффективно аллоцируются, Janet часто оказывается быстрее Python в задачах, где много манипуляций со структурами данных.
Кстати, сборщик мусора здесь простой (stop-the-world), но его поведение можно настраивать. Для большинства скриптовых задач этого более чем достаточно.
Стоит ли пробовать
Janet определенно заслуживает места в инструментарии, если вы:
- Ищете легкий язык для встраивания в C/C++ приложение.
- Любите Lisp-синтаксис, но хотите современные батарейки в комплекте.
- Устали от тяжеловесности Python в маленьких утилитах.
Проект активно развивается, у него живое сообщество в Zulip и вполне адекватная документация. Попробовать язык можно даже в браузере на официальном сайте, не устанавливая ничего на машину.
Конечно, Janet не заменит вам Go или Rust в высоконагруженных системах, но как клей для компонентов или мощный инструмент автоматизации он чертовски хорош. Если вам нужен «Lua на стероидах» с макросами и нормальным сетевым стеком — вы его нашли.
