this very useful answer中,建议我替换此代码:

(defun describe-paths (location edges)
  (apply (function append) (mapcar #'describe-path
               (cdr (assoc location edges)))))

有了这个:
(defun describe-paths-mapcan (location edges)
  (mapcan #'describe-path
               (cdr (assoc location edges))))

我当然从概念上理解了为什么应该这样做,但它没有;第二个变体冻结了我的REPL,CL提示符永远不会返回我得重新启动粘液所以我想知道,mapcan不使用list,而是使用nconc,这是否是原因因此,这些代码块实际上不是功能相同的代码块?
对于好奇的人,我传递这个:
(describe-paths-mapcan 'living-room *edges*)
其中*edges*是:
(defparameter *edges* '((living-room (garden west door)
             (attic upstairs ladder))
            (garden (living-room east door))
            (attic (living-room downstairs ladder))))

以及:
(defun describe-path (edge)
  `(there is a ,(caddr edge) going ,(cadr edge) from here.))

最佳答案

我认为这与describe-edges有关定义如下:

(defun describe-path (edge)
  `(there is a ,(caddr edge) going ,(cadr edge) from here.))

我们可以在那里找到准液你会得到:
(macroexpand '`(there is a ,(caddr edge) going ,(cadr edge) from here.)) ; ==>
(CONS 'THERE
 (CONS 'IS
  (CONS 'A
   (CONS (CADDR EDGE) (CONS 'GOING (CONS (CADR EDGE) '(FROM HERE.)))))))

根据documentation for mapcan的规定,浓缩是破坏性的查看从macroexpand返回的内容的最后一个元素将与它返回的下一个元素共享结构,因此describe-path将形成一个无限循环。
如果您将nconc更改为以下值,它将起作用:
(defun describe-path (edge)
  (list 'there 'is 'a (caddr edge) 'going (cadr edge) 'from 'here.))

10-08 14:32