Стендап Сьогодні 📢 Канал в Telegram @stendap_sogodni

🤖🚫 Контент вільний від AI. Цей пост на 100% написаний людиною, як і все на моєму блозі. Насолоджуйтесь!

10.09.2024

Бібліотека samber/lo: функціональні ідіоми для Golang

Випробував таку нову (для мене) бібліотеку - samber/lo. Знаєте пакет Lodash для JavaScript? Там, де купа зручних функцій для програмування у функціональному стилю? От це таке саме тільки для Go.

Бібліотека вийшла у 2022, після того, як в Go 1.18 зʼявилися дженерики. Та, завдяки дженерикам, вона є швидкою та безпечною.

Та вона дійсно дозволяє писати функціональний код на Go. Наприклад, ось обчислення першого року публікації кожного автора:

lo.MapValues(
  lo.GroupBy(books, func(b Book) string { return book.Author }),
  func(bb []Book) int {
    return lo.Earliest(lo.Map(bb, func(b Book) int { return book.year }))
  },
)

Написав приклад та подумав, що імперативне рішення може було б і ясніше. Не впевнений, що варто робити такі багаторівневі конструкції. З іншого боку, виклики в один рядок на кшталт Flatten чи GroupBy, чи Filter здатні замінити багатомовні цикли та зробити код ясніше. А ще тут є функція Must, якої теж постійно не вистачає, щоб висловити “якщо тут буде помилка, то я зовсім не знаю, що з нею робити”.

Також зазначу, що хоч дженерики здатні виводити типи — тому їх писати не потрібно — але функції потребують явного задання типів. Тому компактне в JS book => book.year перетворюється на func(book Book) int { return book.year. Та це помітно псує код.

Щодо ціни всіх цих абстракцій… Роб Пайк дозволив про це не думати. Я раджу всім спробувати у своїх проєктах цю бібліотеку та думаю, вона знайде свою нішу в вашому коді.