Разбиение функции на несколько строк
Вот некоторый исходный код для примера из удивительной книги "Земля Лисп":
(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 можно не только СОБРАТЬ, но и ПРИЛОЖИТЬ.