Lisp Style вопрос метка локальных функций или нет? - PullRequest
10 голосов
/ 08 марта 2010

Мне было интересно, существует ли стандартная практика использования меток в Лиспе.Я возился с реализацией алгоритма на Лиспе, описанного в первом ответе здесь Генерация перестановок лениво Моя текущая версия использует метки для выделения частей функциональности.

(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))))))

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

Ответы [ 3 ]

7 голосов
/ 08 марта 2010

Нет, все в порядке. Написание именованных функций делает код немного более самодокументируемым и более модульным.

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

Локальные функции также предоставляют возможность добавлять строки локальной документации и описания интерфейса.

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

2 голосов
/ 08 марта 2010

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

1 голос
/ 08 марта 2010

Не будучи ничем иным, как новичком в Lisp, я бы сказал, что вы поступаете правильно: делаете свой код более читабельным, называя куски.

...