tgoop.com/cpplastic/356
Last Update:
Трохи забарився я з вирішенням задач на Advent of Code через відрядження — зараз наздоганяю. Але розвʼязав того тижня задачі восьмого дня на Nim
Вже не згадаю, як саме я на цю мову вийшов колись, але зацікавився одразу. Аж настільки, що купив паперову книгу. Прочитав її, покодив трохи й закинув. Проблема була не стільки у мові, скільки у її розвитку. Якось не відчувалося зрілості в головних мейнтейнерах, версії 1.0 знов-таки не було досі (а мене прям так і тягне на сире лайно: Rust у свій час, потім Nim, Red тощо), ну й купа інших сумнівів.
Але! Версію 1.0 вони все-таки зробили. А потім і 2.0. У мене ось зараз 2.2 стоїть вже. І знаєте шо? А норм!
Синтаксис — така собі суміш Pascal та Python. Є дженеріки, в яких доволі легко обмежити тип якоюсь підмножиною. Я для розвʼязання задачі оперував 2D-координатами: варто було б зробити окремий тип на це, та я обмежився кортежами. Ось, наприклад, перевантажений під мою задачу оператор -
(мінус):
proc `-`[T: int32 | int64](a, b: (T, T)): (T, T) =
((a[0] - b[0]), (a[1] - b[1]))
Дуже лаконічно, але при цьому легко читається, як на мене.
Інша прикольна фіча — Uniform Function Call Syntax. Зазвичай в ООП-мовах, якщо хочете додати метод то якогось типу, ви мусите його описати в самому класі. Деякі мови пропонують різні рішення, щоб це покращити: partial classes, mixins, traits тощо. В Nim ви просто пишете звичайну функцію на кшталт
add
, а потім можете її визивати хоч як add(a, b)
, хоч як a.add(b)
— ці записи тотожні. Для C++ до речі теж є аналогічна пропозиція, але так досі нічого й не впровадили.Окрім цього я вже колись згадував (і в статті) про
discard
. В тому ж C++ можна позначити функцію, яка повертає значення, як [[nodiscard]]
, і тоді її значення не можна проігнорувати без ворнінга. А в Nim навпаки! Якщо функція щось повертає, а ви це значення не використали, то компілятор одразу помилку пише, якщо не проставити явно discard
.Ну й наостанок скажу, що в Nim прям дуже легко писати код, який виконуватиметься під час компіляції. Фактично майже нічого й робити не треба: інколи хіба що прагму до функції додати, інколи кудись
const
поставити. Я у своїй програмі трохи читернув заради швидкодії: я там читаю файл з даними та будую з нього матрицю — все на етапі компіляції. Якщо трохи заморочитися, то можна було б взагалі все рішення обрахувати в компайл-таймі, а прога при запуску його просто в консоль виводитиме Короч, приємна доволі мова. Навіть хз, чому я не використовую.