Разбиение функции на несколько строк

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

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

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

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

1 ответ

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

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

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

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

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

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

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

Другие вопросы по тегам