Обновить
8K+
95
AlexeiZhuravlev@AlexeiZhuravlev

Пользователь

35,1
Рейтинг
9
Подписчики
Отправить сообщение

Спасибо за объяснение! Вы как раз подтверждаете мою мысль — для вас это «всё просто», и я верю. Но в вашем объяснении уже есть «монада», «bind», «>>=», «unsafePerformIO» и «упаковка значений». Для обычного разработчика, который хочет напечатать строку в консоль, это пять новых концепций до первого результата. В Gleam это io.println("hello") — и готово.

Scala не рассматривал, честно. Она мощная, но для side-проекта мне был важен минимальный порог входа. Gleam можно выучить за выходные — у Scala порог существенно выше, особенно если до этого не был в JVM-мире.

Да для примера. Но мне кажется, тут не нарушение DRY, а два разных уровня абстракции. is_premium — это предикат. premium_group — это результат применения предиката к конкретному набору. Они не дублируют друг друга — они на разных этажах.

Да, разворачивается именно так. И вы правы — для строки x.trim().uppercase().append("!") читается лучше. Но в этом и суть: method chaining работает, пока все методы принадлежат одному объекту. Как только нужно протащить данные через функции из разных модулей — parse_request, потом handle_input, потом response.build — методы кончаются, а пайп продолжает работать.

В Gleam нет методов и нет this — функции принадлежат модулям, а не данным. Поэтому string.trim(x) вместо x.trim(). Пайп компенсирует отсутствие методов — и делает это универсально, потому что работает с любой функцией, а не только с методами одного типа.

Кстати, ваша идея про разветвление после filter — это по сути то, что в ФП делается через let. Не промежуточные переменные в императивном смысле, а именованные привязки:

let filtered = items |> list.filter(is_active)
let group_a = filtered |> list.filter(is_premium)
let group_b = filtered |> list.filter(fn(x) { !is_premium(x) })

Пайп не пытается заменить всё — он для линейных цепочек. Когда поток разветвляется — let и отдельные пайпы.

Интересная ниша — язык как инструмент доказательства, а не только разработки. С Lean не работал. Ждем от вас статью про него))

Про Rust — согласен, что он мощнее как язык. Но для моей задачи (голосовой навык, FSM, Redis, конкурентные сессии) его сила избыточна, а BEAM под капотом Gleam даёт модель конкурентности, которой в Rust нет из коробки — лёгкие процессы, изоляция ошибок, supervision trees. Это не про синтаксис, а про рантайм.

Про Go — я в основном занимаюсь архитектурой, кода пишу мало. Go в нашем стеке — не мой личный выбор, а стандарт, который выбирает компания. И его выбирают именно за то, за что вы его критикуете — он простой, предсказуемый, любой новый разработчик входит в проект за короткий срок. Для команд в 10-50 человек это перевешивает элегантность. Отвращение к Go я понимаю, сам в статье написал про бесконечные «if err != nil» — но архитектурные решения принимаются не по ощущениям одного человека, а по стоимости поддержки для всей команды.

Спасибо! Постараюсь подготовить интересный материал.

Логирование в Gleam можно условно разделить так:

Дебаг. Встроенное ключевое слово echo — вставляешь в любое место пайпа, оно пропускает значение через себя и печатает в stderr с указанием файла и строки:

[1, 2, 3]
|> list.map(fn(x) { x + 1 })
|> echo
|> list.map(fn(x) { x * 2 })

Билд-тул предупредит, если забудете убрать перед публикацией. Есть ещё io.debug — делает то же самое, но без метаданных.

Боевое логирование. Пакет logging — обёртка над Erlang logger. Уровни, форматирование, всё стандартно. Есть glimt — более продвинутый, со структурированным JSON-выводом и контекстами.

Сам пайп |> — это синтаксический сахар, а не значение, его нельзя передать куда-то как аргумент. Но можно собрать цепочку в анонимную функцию и передать её:

let transform = fn(x) {
  x
  |> string.trim
  |> string.uppercase
  |> string.append("!")
}

list.map(items, transform)

Говорю как человек с двадцатью годами императивного кода, не как эксперт по Haskell. Моя «боль» — это боль порога входа. Чтобы написать HTTP-сервер на Gleam, мне хватило выходных. Чтобы сделать то же на Haskell, мне сначала нужно понять, почему IO — это монада и зачем мне это знать.

Порог входа — не в синтаксисе, а в количестве концепций, которые нужно усвоить до того, как начнёшь писать что-то полезное. Монады, функторы, классы типов, ленивые вычисления по умолчанию, IO как монада. Каждая по отдельности понятна, но все вместе — это серьёзная нагрузка на мозг.

Уверен, что для тех, кто уже в Haskell, это не боль, а сила. Но я писал статью для таких же как я — Go/Java/C#-разработчиков, которые хотят попробовать ФП без огромных временных затрат.

F# — отличный язык, и для C#-разработчиков это действительно более естественный шаг в ФП — остаёшься на .NET, вся огромная и зрелая экосистема под рукой. Спорить с этим было бы странно.

Разница — в рантайме. F# работает на CLR, Gleam — на BEAM. Это разные модели конкурентности: лёгкие процессы с изоляцией ошибок, supervision trees, hot code reload. Для голосовых навыков, чатов, real-time систем это имеет значение. Для типичного бэкенда — нет, и F# будет практичнее.

А насчёт мутабельных переменных — я в статье честно написал, что их отсутствие в Gleam иногда бесит. F# тут прагматичнее.

Справедливо. Если Java закрывает ваши задачи и экосистема устраивает — нет смысла менять ради синтаксического сахара.

Разница глубже, чем пайпы. Optional и Stream — это ФП-элементы поверх императивного языка. В Gleam иммутабельность и exhaustive pattern matching — не опция, а единственный способ писать код. Нет null, нет исключений, нет мутабельного состояния. Компилятор не даёт забыть ветку в case — вообще, ни одну. В Java sealed classes + switch expressions приближаются к этому, но не заставляют.

Да, пайп-оператор и иммутабельность — это то, что меняет голову навсегда. Я теперь даже в Go-коде ловлю себя на том, что думаю пайпами.

Сочувствую насчёт сокращений. Но BEAM-мышление не теряется — когда будет возможность вернуться, порог входа будет совсем другой.

Представляю, что выдаёт гугл тем, кто впервые пытается загуглить этот язык. Зато запоминается!

Спасибо! Очень знакомая история — после 20 лет в IT думаешь, что тебя уже сложно чем-то удивить. А потом пробуешь ФП на BEAM — и вдруг снова чувствуешь себя джуном, который открывает что-то по-настоящему новое. Давно забытое ощущение.

Интересно, что вы пришли через Elixir. Я сознательно выбрал Gleam именно из-за статических типов — после Go хотелось строгости, но без когнитивной нагрузки Rust. А что в Elixir впечатлило больше всего — BEAM как платформа или сам язык?

Факты это прекрасно и с ними я не спорю. Но откуда взялось значение именно 70?

"Видимо iq ниже 70 — это обязательное требование при приёме на работу на государственное телевидение." - это оценочное суждение автора статьи. Какими фактами оно обосновано? На основании чего вы можете оскорблять журналистов? Вы сами никогда не косячите? А если ошибаетесь, то у вас IQ падает до 70 пунктов?

Алиса, очень интересная и глубокая статья. Спасибо большое за публикацию! Интересно и познавательно было прочитать!

Это не запрещает одновременно тормозить и рулить.

Даже если будет выбор между "гарантированно дать в зад машине впереди" и "начать рулить и будь что будет", я всегда выберу первое. Так же требуют и ПДД. 

Где конкретно ПДД это требуют?

1
23 ...

Информация

В рейтинге
231-й
Откуда
Екатеринбург, Свердловская обл., Россия
Дата рождения
Зарегистрирован
Активность