Lisp Code Formatting - PullRequest
       14

Lisp Code Formatting

36 голосов
/ 12 февраля 2009

Один из людей, который нашел время, чтобы прокомментировать мой другой вопрос о синтаксисе Clojure / LISP, указал, что я не написал свой пример кода стандартным способом LISP. Поэтому он был достаточно любезен, чтобы переписать фрагмент кода, и это очень помогло. Но это подняло еще один вопрос в моей голове. С чего бы это:

(if (= a something)
  (if (= b otherthing)
    (foo)))

, который является стандартным форматированием LISP, предпочтительнее для этой формы:

(if (= a something)
  (if (= b otherthing)
    (foo)
  )
)

именно так я и наивно отформатировал бы этот код из-за своего опыта разработки на C ++. Мне интересно, есть ли какая-то польза от последнего форматирования или это просто укоренившийся стандарт (например, клавиатура QWERTY). Я не пытаюсь спорить - мне просто сложно понять, почему первая форма предпочтительнее. Вторая форма помогает мне легче увидеть структуру кода.

Ответы [ 5 ]

37 голосов
/ 12 февраля 2009

То, как код на Лиспе используется с отступом, похоже на существенный пробел в Python, за исключением того, что он, конечно, не обязателен. Основное правило заключается в том, что вы помещаете элементы в список под друг друга вертикально, если они не находятся на одной строке.

(a (b (c (d e)
         (f g))
      (h i j))
   (k l m n))

Даже не глядя на скобки, вы можете видеть, что (d e) и (f g) являются параметрами для c, (c (d e) (f g)) и (h i j) являются параметрами для b, а (b (c (d e) (f g)) (h i j)) и (k l m n) параметры для a.

В вашем примере он должен быть более правильно отформатирован следующим образом:

(if (= a something)
    (if (= b otherthing)
        (foo)))

    ^   ^
  notice how they line up

Теперь, когда уровень отступа становится значимым, вам больше не нужно полагаться на балансировку круглых скобок для получения этой информации, и, поскольку более компактно размещать их в одной строке с заключительным оператором, это то, что делает Лисперс. Конечно, нет необходимости, чтобы код Lisp форматировался таким образом, но это довольно стандартное соглашение, которое люди используют и на которое можно положиться.

37 голосов
/ 12 февраля 2009

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

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

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

3 голосов
/ 23 февраля 2009

Простой ответ заключается в том, что ваш путь отличается от способа, которым симпатичный принтер Лисп делает вещи. Наличие ОДНОГО ИСТИННОГО ФОРМАТА всегда полезно для кода, а макрос pprint дает вам этот формат, встроенный в язык.

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

1 голос
/ 08 апреля 2015

Вы можете переформатировать код Lisp с помощью пакета Sreafctor: Домашняя страница .

Некоторые демонстрации:

Доступные команды:

  • srefactor-lisp-format-buffer: форматировать весь буфер
  • srefactor-lisp-format-defun: отформатировать текущий курсор без определения в
  • srefactor-lisp-format-sexp: отформатировать текущий курсор sexp.
  • srefactor-lisp-one-line: превратить текущий sexp того же уровня в одну строку; с префиксным аргументом, рекурсивно превращать все внутренние сексы в одну строку.

Команды форматирования также применимы в Common Lisp и Scheme.

Если есть какие-либо проблемы, пожалуйста, отправьте отчет о проблеме, и я буду рад ее исправить.

0 голосов
/ 12 февраля 2009

Когда вам нужно закрыть 10 скобок, это становится действительно неуклюжим.

Когда я использовал для программирования Lisp, я оставлял пробел между закрывающими скобками для открывающих скобок в той же строке и для остальных, чтобы упростить подсчет, например:

(if (= a something)
  (if (= b otherthing)
    (foo) ))

Полагаю, в наши дни это больше не нужно, так как редакторы более полезны.

...