Я задавался вопросом, существует ли общепринятая практика относительно использования маркировок в 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.
Нет, все в порядке. Написание именованных функций делает код немного более самодокументированным и более модульным.
Иногда я также перечислял все переменные, используемые в функциях arglist, и не использовал переменные из включающей функции. Это делает интерфейс немного понятнее и помогает перемещать функцию в коде (при необходимости).
Локальные функции также предлагают возможность добавлять строки локальной документации и описания интерфейсов.
Если локальные функции становятся слишком большими и их также можно использовать извне, я бы извлек их и сделал глобальными.
Я не вижу в этом ничего плохого. Вы делаете два подпроцесса очень понятными и легко разбиваемыми на части, что упрощает понимание того, что на самом деле делает функция, просто глядя на ее тело. Кроме того, теперь при необходимости легко преобразовать внутренние функции в глобальные.
Не будучи никем иным, кроме новичка в Lisp, я бы сказал, что вы поступаете правильно: делаете свой код более читабельным, называя фрагменты.