Около 3-х лет назад, я написал статью о том, как я открыл для себя язык программирования gleam. Тогда я отметил, что gleam не так уж сильно отличается от питона.
Сейчас я решил продолжить дискурс и перенести его в практическую плоскость. Я сделал форк CPython и попросил DeepSeek немного поиграться с синтаксисом. Хорошо, что в питоне обновили парсер - он теперь достаточно гибкий.
В общем, если смотреть с формальной стороны - получился новый язык. Он немного расширяет питон (то есть, является суперсетом), но совсем чуть-чуть. Оставаясь при этом верным главному синтаксическому принципу - значимым пробелам. Целевые рантаймы для этого языка - CPython и BEAM. Они очень разные, поэтому отлично дополняют друг друга.
На картинке вы видите знак вопроса. Он связан с тем, что у нового языка пока нет окончательного названия. Есть только некоторые идеи - они связаны, простите, со свиньями. Также, в конце будет опрос - нужны ли минипиги в программировании. Ответьте, пожалуйста, это очень важно.

Скажу прямо - идея, главным образом, навеяна языком gleam. Это, на самом деле, просто феномен, а не язык. Причём, в полной мере я осознал этот факт уже после того, как написал о нём статью.
Один показательный факт - в gleam нет атомов. Атомы - это такие строки-константы в эрланге, предназначенные для внутреннего использования. Причина, почему их нет - в том, что иногда можно обойтись без них, используя вместо этого фирменные gleam records. Кроме этого, автор считает чрезмерное использование атомов плохой практикой. Но, ввиду того, что атомы самым широким образом используются в эрланге, из-за того, что их убрали, в значительной степени совместимость с эрлангом была нарушена.
Из-за отсутствия атомов, в gleam крайне неудобно пользоваться OTP - центральной для эрланга библиотекой/платформой. Не так давно - то есть, когда уже прошла целая вечность времени - автор всё-таки выпустил "дружественную к gleam" библиотеку для OTP, но она всё равно выглядит очень странно. Главный факт, который хочется отметить - всё это совершенно не имело под собой оснований, кроме каприза автора.
В этом году gleam 10 лет - он появился позже языка zig. У него 22k звёзд на гитхабе, и несколько человек работают над ним full-time. Неплохо, правда? Мне кажется, с таким подходом - это вообще оглушительный успех!
Отсутствие атомов - не единственное противоречие между языком gleam и эрлангом/BEAM. Например, компилятор gleam заставляет вас обработать все возможные случаи в конструкциях let и case - это напоминает парадигму из го для обработки ошибок. В то время, как в эрланге один из принципов - это "let it crash", что означает бросить исключение и позволить процессу умереть.
Лично мне совершенно не близок такой "бунт" gleam против своей целевой платформы, к тому же, добровольное нарушение совместимости выдаёт в авторе крайнюю наивность. Но есть один факт, который является однозначным достоинством gleam. Это - его минимализм. Где-то я видел слайд, где на экран вывели все ключевые слова gleam крупным шрифтом, и потом сказали, что половина из них зарезервирована на всякий случай и сейчас не используется.
Минимализм - это действительно его фишка. Я как-то подумал, что если из питона убрать классы, OOP, все явно мутирующие операции - получится всё равно более богатый по синтаксису язык, чем gleam. Это, кстати, и навело меня на соответствующие мысли.
Ещё есть проект hornbeam.dev, Он демонстрирует, что можно деплоить приложения на питоне, используя BEAM - и получить в результате почти бесплатно кэширование и распределённость.

Ну и, наконец - где-то в твиттере я прочитал: "I decided to build ... (какую-то вещь) because no one needs it". Мне это понравилось - сразу всем понятно, зачем.
Итак, давайте я вам покажу, как выглядит язык. Прежде всего, это форк CPython. Все конструкции питона работают (возможно, с небольшими изменениями), вся семантика остаётся той же. Области видимости переменных - такие же, как в питоне.
В питоне - мутабельный императивный рантайм, он останется таким же. Например, остаются, циклы for. Хотя на платформу BEAM циклы for тащить нет никакого смысла: в питоне есть list/dict comprehensions - это примерно то же самое, но подходит для функционального программирования гораздо лучше.
Но вот основные control structures я хочу сделать выражениями (expressions), как это принято в функциональных языках. Это операторы if, match и with:
exit_code = # хорошо, если бы здесь можно было начинать с новой строки if ready: run_command() else: abort() 1 result = match val: case 0: "Success" case _: "Failure"
Отдельно скажу про оператор match: его я хочу сделать деструктивным. Это значит, что если ни один из вариантов не сматчился, должен случиться MatchError. Всё - согласно принципу "Let it crash".
Дальше возьмём операцию присваивания =. Её я хочу заменить на паттерн-матчинг:
Point(x=x, y=y) = p
Синтаксис - точно такой же, как у case в операторе match, только нельзя использовать условия if. В результате, оператор = должен стать более функциональным во всех смыслах.
И последнее: ещё я бы улучшил работу с пробелами. Чтобы, например, такое парсилось нормально:
items = my_list .filter(None)
Это может быть особенно полезно, если if и match станут выражениями. Возможно, текущие ограничения в питоне, запрещающие переносить на новую строку, связаны с ограничениями предыдущего парсера.
Вот, пожалуй, и всё. Это - мой минимальный пакет изменений в питон, которые сделают его функциональным, почти ничего не ломая. Конечно, это не strict superset, потому что код, который раньше выполнялся без ошибок, теперь может бросить ошибку - из-за того же деструктивного match. Но всё равно - это почти тот же питон.
Кроме минимального пакета изменений, у меня ещё есть опциональный пакет. В духе минимализма из gleam, его, конечно следует отложить. Но всё равно, не могу не поделиться своим синтаксисом.
Вопрос первый: какой может быть функциональный язык без пайплайн-оператора? Хотя, например, в эрланге его нет, и никто не говорит, что эрланг не функциональный. Тем не менее: пайплайн-оператор мне представляется в виде двоеточия:
def is_even(): return x % 2 == 0 [1, 2, 3, 4, 5] ..filter(is_even) ..print()
Также, мне пришла в голову конструкция match def, которая делает паттерн-матчинг нескольких функций с одинаковым названием. Это "склеенные" def и match. Приведу пример с обложки - это сортировка пузырьком в функциональном стиле:
match def bubble_sort(lst: list[int], acc: list[int], was_swapped: bool): case [] = lst: (acc[::-1], was_swapped) case [x] = lst: ([x, *acc][::-1], was_swapped) case [x, y, *rest] = lst if x > y: bubble_sort([x, *rest], [y, *acc], True) case [x, y, *rest] = lst: bubble_sort([y, *rest], [x, *acc], was_swapped)
Но это я просто хотел похвастаться оригинальным синтаксисом. В минимальном варианте, новый язык - это всего лишь плюс-минус обычный питон.
Отдельный вопрос - как это всё будет компилироваться для BEAM. У этого рантайма есть свои особенности, главная из которых - неизменяемые структуры данных. То есть, даже такая конструкция вызывает вопросы:
x += 1
В gleam эту проблему решают так, что у переменной x может быть несколько версий: x@1, x@2 и так далее.
Как я уже говорил, циклы for выбрасываем: вместо них есть list/dict comprehensions. Для словарей есть чудесный оператор-палка:
my_dict |= {'key': value}
Мутирующие операции вроде my_dict['key'] = value не нужны, их тоже выбрасываем. Также, в новом эрланге есть named records - для них оператор-палка тоже пригодится.
В эрланге есть списки - и от питоновских они отличаются тем, что в них добавляют элементы в начало, а не в конец. Получается, методы .append() и .pop() не очень подходят. Я думаю, вместо этого, подойдут shift/unshift:
head = my_list.shift() my_list = my_list.unshift(head)
Но это уже всё детали. Код из репозитория gleam вполне подойдёт для компиляции кода для BEAM. Хотя парситься он может моим форком CPython. Но это тоже детали.
Наконец, мы подошли к самому интересному вопросу - это, конечно, вопрос брендинга. Хотя новый язык очень похож на питон - всё-таки, он отличается. Да и прямой совместимости нет, поэтому файлы вряд ли должны иметь расширение *.py. Другими словами, языку нужно имя, а проекту - лицо (или хотя бы пятачок).
То, что розовый цвет приносит успех - это уже проверено на примере gleam. И я подумал, что можно разыграть счастливую свинскую карту и поместить на логотип розового поросёнка. Но вопрос о названии оставался открытым: piglang - это как-то слишком толсто. Всё-таки, нужен именно поросёнок, а не взрослая свинья.
Тут я вспомнил, что свиньи с давних пор были персонажами английских сказок и подумал, что, вероятно, в английском языке есть достаточно много слов для передачи звуков, которые издают свиньи. Так и оказалось: "oink" - это общее хрюканье, "grunt" - "ворчание" взрослого кабана, и "squeal" - визжание поросёнка. Немного примерив последнее слово, я решил, что оно может подойти.
squea-lang, как вам такой вариант? Файлы исходного кода могут иметь расширение .ea, на логотипе - розовый поросёнок. В конце концов, минипиги крайне фотогеничные. А вы что думаете?