красивая печать и расширение

РЕДАКТИРОВАТЬ Я не просто спрашиваю об "отступе" каждой отдельной строки кода, но о "красивой печати" и/или более широком определении "отступа", где строки будут сгруппированы/разделены в зависимости от того, что они содержат.

Вот функция (которую я написал для решения задачи Эйлера, но суть не в этом: я мог написать ее по-другому), которую я пытаюсь красиво напечатать:

Версия с отступом вручную:

(apply max
       (flatten
        (for [x (range 100 1000)]
          (map
           #(if (= (str (* x %)) (apply str (reverse (str (* x %)))))
              (* x %)
              0)
           (range x 1000)))))

По-видимому, это не единственный истинный стиль отступа/печати Lisp, и, поскольку я хотел бы получить хорошие привычки с самого начала, я попытался "красиво напечатать" его, выполнив следующие действия из Emacs'а slime-repl clojure РЕПЛ:

user> (doc pprint)      ;; just to show which version of pprint I'm using
clojure.pprint/pprint
...

Итак, я попытался сделать:

user> (pprint '(apply max
       (flatten
        (for [x (range 100 1000)]
          (map
           #(if (= (str (* x %)) (apply str (reverse (str (* x %)))))
              (* x %)
              0)
           (range x 1000))))))

И я получил следующее:

(apply
 max
 (flatten
  (for
   [x (range 100 1000)]
   (map
    (fn*
     [p1__13958#]
     (if
      (=
       (str (* x p1__13958#))
       (apply str (reverse (str (* x p1__13958#)))))
      (* x p1__13958#)
      0))
    (range x 1000)))))

Насколько я понимаю, нотация #(...) для лямбды - это "макрос чтения". Итак, как я могу красиво печатать, не запуская расширение макросов? В более общем плане: как я могу красиво напечатать «то, что я вижу в своем текстовом редакторе»?

Кроме того, нормально ли, что почти все идет с новой строки? Например:

(apply
 max
 (flatten
  (for
   [x (range 100 1000)]
   (map
    ...

кажется пустой тратой некоторого вертикального экрана. Это именно так должен быть отступ в коде на Лиспе?

И последний связанный с этим вопрос: можно ли настроить Emacs для «красивой печати» выбранной области или всего буфера .clj?


person Cedric Martin    schedule 02.05.2012    source источник


Ответы (3)


Не существует «официального» способа сделать отступ в коде lisp, но мне нравится, как режим clojure делает отступы в коде clojure (см. ниже).

Я не знаю, почему pprint печатает код именно так, но согласно этому, это ранний выпуск, в котором еще не реализованы все функции.

Для части отступа emacs вы можете взглянуть на clojure-mode.

person Daan    schedule 02.05.2012
comment
Не существует "официального" способа сделать отступ в коде на Лиспе. Нет официального способа сделать отступ в коде на Лиспе... А... Я думал, что он есть. Или, по крайней мере, культурно приемлемый способ сделать это. Например, довольно широко распространено мнение, что никогда не следует помещать закрывающие скобки в новую строку: ни один красивый принтер не делает этого, и почти ни один код на Лиспе, написанный знающими программистами на Лиспе, не делает этого. Если нет официального стандарта, то я ищу наиболее распространенный способ форматирования кода Lisp; ) - person Cedric Martin; 02.05.2012
comment
Отступ Clojure-mode, вероятно, близок к этому. Это более или менее похоже на отступ, используемый на clojure.org и во многих библиотеках. - person Daan; 02.05.2012

Самое близкое, что я видел к консенсусу, - это «сделать отступ, как это делает Emacs», я полагаю, что политически правильно, я должен включить следствие «сделать отступ, как это делает vim». другие редакторы, такие как eclipse+CCW, похоже, довольно точно соответствуют этому. хотя красивый принтер по умолчанию добавляет больше новых строк.

person Arthur Ulfeldt    schedule 02.05.2012
comment
Я поставил +1, но все же... Почему pprint расширяет лямбду? Это так должно работать? - person Cedric Martin; 03.05.2012

Вот что я сейчас делаю:

(defn pprint-code [code]
  (with-pprint-dispatch code-dispatch
    (binding [*print-suppress-namespaces* true]
      (pprint code))))

ПРИМЕЧАНИЕ. Найдите файл clojure.pprint, чтобы разрешить free-vars.

Это, безусловно, улучшение. Я до сих пор точно не знаю, как настроить *print-miser-width* и/или *print-right-margin*, чтобы получить лучший результат. YMMV. Моя текущая говядина связана с (авто-) gensyms - я хочу, чтобы они были разобраны во время печати в определенных контекстах.

В идеале формы/функции могут определять свои собственные правила форматирования, например. let-bindings всегда должны быть на отдельных строках. Я не знаю, как это сделать с помощью clojure.core.

Для справки см. этот обзор.

person Ian Tegebo    schedule 04.07.2014