tgoop.com/cpplastic/367
Last Update:
Щоразу, як дивлюся або читаю пана Соловйова, хочеться спробувати Clojure, особливо на тлі незрозумілостей з Red.
Ліспи з їхньою купою варіацій і REBOL з наразі єдиним нащадком Red — це D&D
Я вже намагався зробити підхід до Clojure десять років тому, але вочевидь був неготовий ментально. Зараз же зробив другу спробу і… не зміг себе пересилити: дивлюся в цей короткий лаконічний код, а подумки бачу, як JVM нестямно жере памʼять мого компа, і уявляю, як мені доведеться йти крізь ієрархію тек, щоб нарешті знайти там свій єдиний файл з кодом.
На щастя з одного зі стрімів пана Соловйова я дізнався про існування мови Janet
На початку було дуже складно, зокрема через відсутність навичок роботи з реплом та редагування лісп-коду. «Кляті дужки!»
Одним із сюрпризів став той факт, що на ліспі взагалі-то можна (і дуже легко) писати імперативно. Чогось був переконаний, що це чисто ФП-шна штука на кшталт Haskell. Тож тут одразу +1 до приємності.
У Janet також є фішка з підтримкою PEG, якою вони надихнулися зокрема з REBOL/Red. Для задачі воно було непотрібно — можна було тупо працювати з charʼами, але мені кортіло спробувати, тож я запарсив файл отакою граматикою:
(defn parse-input [input]
(def grammar
'{:wall (/ "#" :w)
:empty (/ "." :e)
:box (/ "O" :b)
:robot (/ (* (line :row) (column :col) "@") :r)
:cell (+ :wall :empty :box :robot)
:line (* (group (some :cell)) "\n")
:grid (group (some :line))
:up (/ "^" :up)
:down (/ "v" :down)
:left (/ "<" :left)
:right (/ ">" :right)
:direction (+ :up :down :left :right (? "\n"))
:moves (group (some :direction))
:main (*
:grid (-> :row) (-> :col)
"\n"
:moves)})
(let [[grid row col moves] (peg/match grammar input)]
[[(dec row) (dec col)] grid moves]))
Через наявність PEG у Janet немає підтримки регулярних виразів, бо в принципі вони непотрібні. Я не певен, чи це добре: все-таки інколи фігачнути маленький regexp швидше й легше, але ок. Іншим мінусом Janetʼівського
peg/match
є той факт, що вона працює тільки з рядками на вході. Якщо порівнювати з ріболівським parse
, це сильний недолік, адже там вони прям блоки коду (а код — це дані) парсять тим же самим парсом. Це логічніше, бо яка різниця, що ви отримуєте на вхід: список текстових літер чи список кейвордів? Через це нові діалекти в REBOL робити легше й приємніше.Із загальних приємностей Janet: є fibers, threads, channels, streams тощо — все, що потрібно, є. Також доволі розвинена стандартна бібліотека, менеджер пакетів, FFI взаємодії з сішним кодом.
До синтаксису звикаєш значно швидше, ніж здалося на початку. А ось до назв функцій трохи повільніше. Мій чинний код стопудєй максимально далекий від ідіоматичного і ще далі від оптимального, але я отримав задоволення, доки писав!
Другу задачу, яка фактично є
Я ще згодом напишу підсумки про саму подію, а зараз можу впевнено сказати, що Janet — це одна з моїх нових улюблених мов!