Не далее как на этих выходных я написал статью о том, что хочу сделать новый язык для BEAM со статической типизацией. Получив большой фидбэк (большая его часть была, как обычно, между строк), хочу представить вашему вниманию издание 2е - полностью переработанное. Так - чтобы и вашим и нашим.
Новый план состоит в том, чтобы использовать синтаксис Elixir (да!) как он есть - ну, разве что, типы в него добавить. Сделать соответствие модулей и физических файлов 1:1. Синтаксис для импортов сделать наподобие того, который в питоне.
Макросов в berry не будет. Но макросы из библиотек эликсира использовать будет можно! Это нужно, чтобы можно было пользоваться библиотеками вроде Ecto и Phoenix. Импортировать макрос можно будет так же, как обычную функцию. При этом под капотом будет происходить всё то же самое, как в эликсире.
Таким образом, хотите использовать макросы - езжайте в свой эликсир, пишите их там. А у нас такое не приветствуется. Короче говоря, новый план в том, чтобы исправить Elixir. Вы хотите спросить, не хочу ли я поделиться этой идеей с более широким сообществом? Я уже сделал это! А вот, какая была реакция - об этом читайте под катом.
* * * * * * * * * * * * * * * *
Думаю, первый вопрос, который у вас возник, когда вы прочитали предисловие - это можно ли в Elixir добавить типы. Если вы читали предыдущую статью, то должны догадаться, что - можно:
def my_fun(x: Integer, m: Map) -> Bool do
end
Если вы используете внутри функции паттерн-матчинг, аннотации можно писать за скобками:
def my_fun([head | tail]) when head: Integer -> Bool do
Обычное использование guards - через условия в скобках после типа:
def my_fun(s: String(starts="berry"), m: Map(size>0)) -> Nil do
Использование в case:
case m do
Map(size>0) -> ...
%{x: x} -> ...
end
В эрланге (и эликсире) нельзя получить тип текущего значения обычными способами, поэтому, если там стоит тип - это значит, его там явно указали.
Как видите, добавить типы в эликсир вполне осуществимо. Не утруждая себя обдумыванием дальнейших деталей, я решил сразу поделиться идеей с сообществом, написав на форум текст такого содержания:
Для тех, кто не хочет читать мелкий шрифт, пересказываю содержание: всем известно, что в эликсире 2 минуса - это макросы и отсутствие типов. Народная мудрость гласит, что минус на минус даёт плюс. В связи с этим, почему бы не сделать версию Elixir 2.0, в которой одновременно добавить типы и убрать возможность писать свои макросы. Учитывая хайп, который вызовет добавление статической типизации, все очень быстро мигрируют на Elixir 2.0. В конце добавил успокоительные фразы о том, что не обязательно выпиливать макросы целиком, часть можно оставить, наиболее нужные.
Я думаю, читатели примерно представляют, что, в ответ на это предложение, я получил много ярких реплик. Вот, например, одна из них :
"На данном этапе, я уверен, что это первоапрельская шутка, но сейчас она не подходит к сезону". В общем, модераторы спохватились, только когда в топике уже было под 30 сообщений - так что это успех. Я не ожидал даже, что он первичную модерацию пройдёт. Основная мысль выступающих была, что макросы - это одна из важнейших фич языка, и что выпиливать её никто не станет даже под дулом пистолета.
Таким образом, напротив пункта "общение с сообществом" можно смело ставить галочку. Но вернёмся к плану по внедрению berry-lang.
Раз уж начали говорить про макросы - у меня есть очень простая идея, как с ними быть. В berry можно использовать макросы, написанные на Elixir - их можно импортировать из пакета как обычные функции. При этом, писать макросы на berry нельзя: в конце концов, эликсир никуда не девается, хотите - пишите свой макрос на нём и используйте эту библиотеку как зависимость. Таким образом, мы получаем возможность использовать Ecto, Phoenix и другие библиотеки, богатые на ключевые слова.
По поводу модулей: избавившись от макросов и от необходимости в конструкции "use", мы теперь можем иметь прозрачную систему модулей и имортов. Каждый модуль соответствует файлу, где лежит его исходный код и называется так же. Конструкция "defmodule", получается, не нужна, а всё что было под этой конструкцией, попадает в модуль berry.
Кстати, какое расширение выбрать для модулей, *.be?
Для импортов я собирался выбрать синтаксис из питона:
from pak.more_pak import something
Но потом вспомнил, что в Ecto есть макрос from. Лучше, чтобы его можно было использовать, не переименовывая. Можно взять более скромный вариант, например, из gleam:
import pak/more_pak {something}
Разумеется, импорт макросов будет только выглядеть как обычный импорт, под капотом же, при компиляции будет происходить то же самое, что и в эликсире.
А Вы что об этом думаете, дорогой читатель?