在这个非常有用的答案中,有人建议我可以替换这段代码:
(defun describe-paths (location edges)
(apply (function append) (mapcar #'describe-path
(cdr (assoc location edges)))))
Run Code Online (Sandbox Code Playgroud)
有了这个:
(defun describe-paths-mapcan (location edges)
(mapcan #'describe-path
(cdr (assoc location edges))))
Run Code Online (Sandbox Code Playgroud)
我当然从概念上理解为什么这应该有效,但事实并非如此; 第二个变体冻结我的REPL,CL提示永远不会返回.我必须重启SLIME.所以我查了一下,我想知道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))))
Run Code Online (Sandbox Code Playgroud)
和:
(defun describe-path (edge)
`(there is a ,(caddr edge) going ,(cadr edge) from here.))
Run Code Online (Sandbox Code Playgroud)
我认为这与此有关describe-edges.它被定义为:
(defun describe-path (edge)
`(there is a ,(caddr edge) going ,(cadr edge) from here.))
Run Code Online (Sandbox Code Playgroud)
那里的quasiquote我们可以macroexpand..你得到:
(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.)))))))
Run Code Online (Sandbox Code Playgroud)
根据mapcan的文档,破坏性地完成了连接.查看返回的最后一个元素describe-path将与它返回的下一个元素共享结构,因此nconc将进行无限循环.
如果您要更改describe-edges为以下内容,它将起作用:
(defun describe-path (edge)
(list 'there 'is 'a (caddr edge) 'going (cadr edge) 'from 'here.))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
161 次 |
| 最近记录: |