Каждый раз принимаясь за изучение Clojure обращал внимание, что читать хорошо отформатированный код после некоторой тренировки становится легко. Но вот решать задачки из проекта эйлер, форматируя таким “правильным” образом код, для меня стало большой проблемой.
Никаких разъяснений на русском я не нашёл, потому решил восполнить пробел переведя коротенькую инструкцию с английского.
По сути своей код на Clojure – просто набор скобоклитералов, потому без грамотной расстановки отступов его тяжело читать. Clojure с расстановкой отступов выглядит примерно так:
(defn my-zipmap [keys vals]
(loop [map {}
ks (seq keys)
vs (seq vals)]
(if (and ks vs)
(recur (assoc map (first ks) (first vs))
(rest ks)
(rest vs))
map)))
(my-zipmap [:a :b :c] [1 2 3])
Основное правило таково: продолжение списка на новые строки пишем с отступом. Так, строка начинающаяся с (loop имеет отступ в 2 пробела относительно строки (defn потому что список начинающийся с (loop – это непосредственный элемент списка начинающегося с (defn.
Однако ниже автор кода отступает от основного правила, выравнивая строки (recur и (and, а не отступая 2 пробела от (if.
Также вектор начинающийся с [map начинается внутри строки (не с новой строки) потому 2 следующие строки выравниваются по позиции следующей за [
В результате правила таковы:
1. Отделяем продолжения строки двумя пробелами если неприменимы следующие правила
2. При возможности вместо отступа выравниваем открывающие скобки (, [ или {
3. При продолжении внутреннего списка (списка начататого не с начала строки) выравниваем строки по первым символам элементов этого списка
По сути, выравнивание всегда происходит относительно скобки (, [ или { к которой принадлежит выравниваемый элемент.
Конечно без некоторой привычки читать и писать по такой схеме сложно.
Для Lisp'ов типично обилие закрывающих кавычек:
(defn supply-arg [arg flist]
(loop [flist flist cnter 0]
(if (first flist) (do ((first flist) arg)
(recur (rest flist) (+ 1 cnter))))))
Справиться с ними, а так же расставить отступамы помогают текстовые редакторы заточенные под редактирование Clojure.Для начала всё. Есть смысл продолжать выкладывать статьи по Clojure?
Отсюда: en.wikibooks.org/wiki/Learning_Clojure/Coding_Conventions