Лисп скобки - PullRequest
       44

Лисп скобки

43 голосов
/ 05 февраля 2010

Почему Лисперс форматирует свой код, как показано в примере 1, а не как показано в примере 2? Для меня (и, я полагаю, для большинства других, кто имеет опыт программирования, отличный от Lisp), форматирование, показанное в примере 2, будет проще для чтения. Есть ли какая-то особая причина, по которой Лисперс предпочитает стиль образца 1?

Образец 1

(defun factorial (n)
  (if (<= n 1)
    1
    (* n (factorial (- n 1)))))

Образец 2

(defun factorial (n)
  (if (<= n 1)
    1
    (* n (factorial (- n 1)))
  )
)

Ответы [ 13 ]

33 голосов
/ 05 февраля 2010

Среды LISP IDE стремятся автоматически балансировать скобки и управлять отступами на основе уровня вложенности. Образец 2 не дает никаких преимуществ в таких ситуациях.

В наследии C / FORTRAN / Pascal вы, как правило, подчеркиваете последовательность над вложением (деревья разбора кода меньше и шире). Конец области видимости является более значимым событием в вашем коде: следовательно, акцент был и все еще в некоторой степени важнее.

21 голосов
/ 05 февраля 2010

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

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

(a)

а не

(a
)

Что следует из этого:

(defun foo (bar)
  (foo (bar (baz
              ...
             )
         ...
        )
    ...
   )
 )

против.

(defun foo (bar)
  (foo (bar (baz ...) ...) ...))

Одна из основных идей при редактировании текста на Лиспе заключается в том, что вы можете выбрать список, дважды щелкнув по скобкам (или с помощью команды клавиши, когда курсор находится внутри выражения или в скобках). Затем вы можете вырезать / скопировать выражение и вставить его в другую позицию в другой функции. Следующим шагом является выбор другой функции и переопределить функцию. Готово. Нет необходимости удалять или вводить новые строки для закрытия скобок. Просто вставьте и сделайте отступ. Это просто вписывается. В противном случае вы либо потратите время на форматирование кода, либо вам придется переформатировать код с помощью какого-либо инструмента редактора (чтобы закрывающие скобки были на своих строках. В большинстве случаев это создаст дополнительную работу и мешает перемещать код.

Есть один случай, когда опытный Лисперс когда-нибудь напишет закрывающие скобки в своей строке:

(defvar *persons*
   (list (make-person "fred")
         (make-person "jane")
         (make-person "susan")
         ))

Здесь это означает, что могут быть добавлены новые лица. Поместите курсор непосредственно перед вторыми закрывающими скобками в последней строке, нажмите c-o (открытая строка), добавьте предложение и сделайте отступ в скобках, чтобы они снова выровнялись. Это избавляет от необходимости искать правильные скобки, а затем нажимать клавишу возврата, когда все скобки закрыты в одной строке.

15 голосов
/ 05 февраля 2010

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

В Python вообще нет закрывающих скобок или end ключевых слов, и Pythonistas живут просто отлично.

9 голосов
/ 05 февраля 2010

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

Что касается того, должна ли последняя форма быть

(* n (factorial (- n 1)))

или

(* n
   (factorial (- n 1)))

, что в основном сводится к личным предпочтениям и тому, сколько всего происходит в коде (в этом случае я бы предпочел первое из-за того, что в коде так мало происходит).

5 голосов
/ 06 марта 2012

Почему программисты на C пишут такие вещи, как:

((a && b) || (c && d))

вместо

((a && b) || (c && d
             )
)

Разве №2 не будет легче читать? :)

Серьезно, однако, стиль закрытой группы работает хорошо и для других языков.

#include <stdlib.h>
#include <stdio.h>

int main(void)
{ int i, j, k;
  for (i = 0; i < 1000; i++)
  { for (j = 0; j < 1000; j++)
    { for (k = 0; k < 1000; k++)
      { if (i * i + j * j == k * k)
        { printf("%d, %d, %d\n", i, j, k); } } } }
  return 0; }

Через некоторое время вы не «видите» фигурные скобки, а просто структуру, заданную отступом. если / еще выглядит так:

if (cond)
{ stmt;
  stmt; }
else
{ stmt; }

переключатель:

switch (expr)
{ case '3':
    stmt;
    break;
  case '4':
  { stmt;
    break; } }

Структура:

struct foo
{ int x;
  struct bar
  { int y; };
  union u
  { int a, b;
    char c; }; };
5 голосов
/ 05 февраля 2010

Помимо того факта, что большинство Lisp IDE используют сопоставление парен, количество места, которое вы бы использовали для написания любой разумной программы, было бы просто смешно! Вы получите запястный туннель от всей прокрутки. Программа из 1000 строк будет близка к миллиону строк кода, если вы поместите все закрывающие скобки в их собственную строку. Он может выглядеть красивее и его легче читать в маленькой программе, но эта идея не будет хорошо масштабироваться.

4 голосов
/ 05 февраля 2010

Я столкнулся с той же дилеммой в PHP, используя инфраструктуру CakePHP и ее множество вложенных array() структур, иногда глубиной 5+. Через некоторое время я понял, что быть ОКР по поводу заключительной скобки ничего не стоило, кроме как потратить драгоценное время на разработку и отвлечь меня от конечной цели. Отступ должен был быть самым полезным аспектом форматирования.

3 голосов
/ 05 февраля 2010

Просто первая и очевидная причина: 4 LOC в первом случае против 7 LOC во втором.

Любой текстовый редактор, который знает синтаксис LISP, будет подсвечивать ваши совпавшие / несоответствующие скобки, так что это не проблема.

3 голосов
/ 05 февраля 2010

Экономия всего пространства кажется основной причиной. Если он почти так же удобочитаем (особенно когда вы привыкли к синтаксису), зачем использовать дополнительные 3 строки.

2 голосов
/ 06 февраля 2010

Поскольку программисты на Лиспе смотрят на отступ и «форму», а не на скобки.

...