Lisp Стиль вопрос метки локальные функции или нет?
Мне было интересно, существует ли стандартная практика использования меток в Lisp. Я возился с реализацией Lisp алгоритма, описанного в первом ответе здесь ленивно создавая перестановки
В моей текущей версии используются метки, чтобы разбить части функциональности.
(defun next-permutation (pmute)
(declare (vector pmute))
(let ((len (length pmute)))
(if (> len 2)
(labels ((get-pivot ()
(do ((pivot (1- len) (1- pivot)))
((or (= pivot 0)
(< (aref pmute (1- pivot))
(aref pmute pivot)))
pivot)))
(get-swap (pivot)
(let ((swp (1- len)))
(loop for i from (1- len) downto pivot do
(if (or (and (> (aref pmute i)
(aref pmute (1- pivot)))
(< (aref pmute i) (aref pmute swp)))
(< (aref pmute swp) (aref pmute (1- pivot))))
(setf swp i)))
swp))
(next (swp pivot)
(rotatef (aref pmute (1- pivot)) (aref pmute swp))
(reverse-vector pmute pivot (1- len))))
(let ((piv (get-pivot)))
(if (> piv 0)
(next (get-swap piv) piv)
nil))))))
Так как каждая метка называется только один раз, мне было интересно, считается ли это плохой практикой, поскольку единственная причина для этого в этом случае - по эстетическим соображениям. Я бы сказал, что текущая версия с ярлыками более ясна, но это может противоречить общей мудрости, о которой я не знаю, новичок в Lisp.
Ответы
Ответ 1
Нет, все в порядке. Запись названных функций делает код немного более самодокументированным и более модульным.
Иногда я бы также перечислял все переменные, используемые в функциях arglist, и не использовал переменные из закрывающей функции. Это делает интерфейс немного понятнее и помогает перемещать функцию в коде (при необходимости).
Локальные функции также позволяют добавлять локальные строки документации и описания интерфейсов.
Если локальные функции становятся слишком большими, и они также могут использоваться снаружи, я бы извлек их и сделав их глобальными.
Ответ 2
Я не вижу в этом ничего плохого. Вы делаете эти два подпроцесса очень ясными и легкими для куска, что позволяет легко понять, что функция действительно делает, просто глядя на тело. Также его теперь легко продвигать внутренние функции в глобальные функции, если вам нужно.
Ответ 3
Не будучи чем-то другим, кроме новичка Lisp, я бы сказал, что вы поступаете правильно: сделать ваш код более читаемым, называя куски.