Управление количеством скобок в clojure

Я новичок в clojure, и главное, с чем я борюсь, - это писать читаемый код. Я часто заканчиваю с функциями, подобными приведенным ниже.

(fn rep 
  ([lst n]
    (rep (rest lst)
    n
    (take n 
      (repeat (first lst)))))
  ([lst n out]
    (if
      (empty? lst)
      out
      (rep 
        (rest lst) n
        (concat out (take n 
          (repeat 
            (first lst))))))))

С большим количеством сборки конечных скобок. Каковы наилучшие способы сокращения этого или форматирования таким образом, чтобы было легче обнаружить отсутствующие скобки?

8 ответов


редактор, который окрашивает скобки, чрезвычайно полезен в этом случае. Например, вот как выглядит ваш код в моем редакторе vim (используя vimclojure):

Rainbow colors

поскольку вы не сказали, какой Редактор вы используете, вам нужно будет найти функцию радужной окраски для вашего редактора соответствующим образом.


использование Emacs paredit mode (эмулируется в нескольких других редакторах тоже) означает, что вы, как правило, - если вы не копируете/вставляете с помощью мыши/принудительных неструктурированных выборов-дело с соответствующими скобками/скобками/скобками и связанным отступом без подсчета.

Emacs с https://github.com/technomancy/emacs-starter-kit (настоятельно рекомендуется!) по умолчанию paredit включен для clojure. В противном случае см. http://emacswiki.org/emacs/ParEdit


в дополнение к редактору, поддерживающему сопоставление скобок, вы также можете попытаться сделать свой код менее вложенным. Я считаю, что ваша функция может быть переписана как:

(defn rep [coll n] (mapcat (partial repeat n) coll))

конечно, это скорее искусство (ремесло), чем наука, но некоторые указатели (в случайном порядке):

  • проблемы 4clojure и их решения топ-пользователями (видно после решения конкретных проблем) - я считаю, что Крис Хаузер есть под ручкой chouser
  • говоря о CH - "радость Clojure" является очень полезным читать
  • просмотр документов на clojure.core-там много полезных функций
  • -> и ->> макросы потоков являются очень полезно для выравнивания вложенного кода
  • stackoverflow-некоторые из самых ярких и полезных людей в мире отвечают на вопросы там; -)

Я не могу достаточно сильно повторить, насколько ценно использовать paredit или какую-то подобную функцию в другом редакторе. Это освобождает вас от заботы о родителях-они всегда идеально подходят для себя и утомительных, подверженных ошибкам задач редактирования, таких как " изменить (foo (bar x) y) на (foo (bar x y))" стало одним нажатием клавиши. В течение недели или около того паредит будет расстраивать вас до невероятности, поскольку он мешает вам делать вещи вручную, но как только вы узнаете автоматические способы обращения с родителями, вы никогда не сможете возвращаться.

недавно я слышал, как кто-то сказал, и я думаю, что это примерно точно, что писать lisp без paredit-это как писать java без автозаполнения (возможно, но не очень приятно).


(fn rep 
  ([lst n]
    (rep lst n nil))
  ([lst n acc]
    (if-let [s (seq lst)]
      (recur (rest s) n (concat acc (repeat n (first s))))
      acc)))

это более читабельно, я думаю. обратите внимание, что:

  • вы должны использовать recur при рекурсии хвоста
  • вы должны проверить с seq - смотрите http://clojure.org/lazy
  • повторить можно считать
  • concat упадет на ноль, что экономит повторение себя
  • вам не нужно начинать новую строку для каждого открытого парень

что касается parens - ваш редактор/ide должен позаботиться об этом. Я печатаю вслепую, так что простите, если я ошибаюсь...

[код Рафал Довгирдовские Короче, я тоже учусь...]

[updated:] после повторного чтения ссылки "ленивый", я думаю, что я неправильно обрабатывал ленивые последовательности,


Я не уверен, что вы можете избежать всех скобок. Тем не менее, то, что я видел, шепот делает, это использовать редактор с paren matching/highlight и, возможно, даже радужные скобки: http://emacs-fu.blogspot.com/2011/05/toward-balanced-and-colorful-delimiters.html

честно говоря, это те функции, которые были бы полезны и для редакторов без Lisp:)


всегда используйте 100% переработанные закрывающие скобки, сделанные из по крайней мере 75% пост-потребительских материалов; тогда вам не нужно чувствовать себя так плохо из-за использования так много.


Это вам нравится. Задача редактора-отображать код в любом стиле, который предпочитает читатель. Мне нравится иерархический древовидный формат C-стиля с одиночными скобками на собственных линиях (все шепотки кипят от ярости :-)))))))))))))

но, я иногда использую такой стиль:

  (fn rep 
  ([lst n]
    (rep (rest lst)
    n
    (take n 
      (repeat (first lst)) )  )   )    )

что является обновлением традиционного стиля, в котором скобки разнесены (уровень ветви log2)

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

Не могу дождаться, когда кто-то напишет приличный редактор в Clojure, хотя это не текстовый редактор, а выражение editor**, затем проблема форматирования уходит. Я сам пишу, но на это нужно время. Идея состоит в том, чтобы редактировать выражения, применяя к ним функции, и я перемещаюсь код с застежкой-молнией, выражение за выражением, а не словами или символами или строками. Код представлен любой функцией отображения, которую вы хотите.

* * да, я знаю, что есть emacs/paredit, но я попробовал emacs и мне это не понравилось.