这个自我参考是什么?
可以用其他任何方式编写吗?
有什么优势吗?
(defmacro sublet (bindings% &rest body)
(let ((bindings (let-binding-transform
bindings%)))
(setq bindings
(mapcar
(lambda (x)
(cons (gensym (symbol-name (car x))) x))
bindings))
`(let (,@(mapcar #'list
(mapcar #'car bindings)
(mapcar #'caddr bindings)))
,@(tree-leaves
body
#1=(member x bindings :key #'cadr)
(caar #1#)))))
答案 0 :(得分:4)
这只是在其他地方重用结构的一种方式。在宏中你有:
(tree-leaves body
#1=(member x bindings :key #'cadr)
(caar #1#))
这只是一种奇特的写作方式:
(tree-leaves body
(member x bindings :key #'cadr)
(caar (member x bindings :key #'cadr)))
从积极的方面来看,如果您更正了member
表单中的错误,则会将其修复到两个位置,但它会运行相同的代码两次,如果member
价格昂贵这不是明智的做法。然而它是一个宏,因此在编译时运行,并且member
在商城列表上相当快(小= =数百万元素或以下)所以我想如果你阅读参考文献就不会有问题与任何其他CL代码一样好。对于其他类型的lispers来说,替代方案可能更具可读性:
(let ((found (member x bindings :key #'cadr)))
(tree-leaves body found (caar found)))