Подтвердить что ты не робот

Lisp Форматирование кода

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

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

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

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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

Код с отступом Lisp имеет вид как существенное пробел в 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

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

Ответ 3

Простой ответ заключается в том, что ваш способ - это не то, что делает Lisp принт-принтер. Наличие ONE TRUE FORMAT всегда полезно для кода, а макрос pprint предоставляет вам этот формат, встроенный в язык.

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

Ответ 4

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

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

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

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

Команды форматирования можно использовать и для Common Lisp и для схемы.

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

Ответ 5

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

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

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

Я думаю, что эти дни больше не нужны, поскольку редакторы более полезны.