Разбиение функции на несколько строк - PullRequest
2 голосов
/ 18 ноября 2010

Вот некоторый исходный код для примера из удивительной книги «Земля Лисп»:

(defun random-node ()
  (1+ (random *node-num*)))

(defun edge-pair (a b)
  (unless (eql a b)
     (list (cons a b) (cons b a))))

(defun make-edge-list ()
    (apply #'append (loop repeat *edge-num*
                          collect (edge-pair (random-node) (random-node)))))

Поскольку у меня нет инстинкта Lisp , я считаю полезным разбить метод на несколько строк (как императивный стиль) и затем попытаться преобразовать его в функциональный стиль.

Не могли бы вы помочь мне разбить функцию make-edge-list на несколько строк?

1 Ответ

1 голос
/ 18 ноября 2010

Линии не имеют смысла в Лиспе. Нотация Lisp основана на s-выражениях, и текстовая строка не видна Lisp во время оценки. Вы можете любым способом разбить выражение на пробел.

(defun make-edge-list ()
   (apply #'append
          (loop repeat *edge-num*
                collect (edge-pair (random-node)
                                    (random-node)))))

Вы должны прочитать код так:

  • каждая пара ребер - это список значений. Каждый минус хранит позицию.
  • цикл возвращает список пар ребер.
  • Затем к этому списку добавляется append и возвращает список значений. Список conses действительно список позиций.

Обратите внимание, что функция имеет несколько небольших проблем:

  • APPLY работает не для списков произвольной длины. Так что будем надеяться, что этот список не слишком длинный.

  • Что еще более важно, применение функции APPEND на самом деле не нужно, если мы слегка изменим LOOP. LOOP можно не только СОБРАТЬ, но и ПРИЛОЖИТЬ.

...