Common lisp 这个自引用代码做什么?
这是什么自我参照 可以用其他方式写吗 有什么优势吗Common lisp 这个自引用代码做什么?,common-lisp,Common Lisp,这是什么自我参照 可以用其他方式写吗 有什么优势吗 (defmacro sublet (bindings% &rest body) (let ((bindings (let-binding-transform bindings%))) (setq bindings (mapcar (lambda (x) (cons (gensym (symbol-name (car x))) x))
(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#)))))
这只是在其他地方重用结构的一种方式。在宏中,您有:
(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)))
从积极的一面来看,如果您纠正了成员表单中的错误,您将在两个地方修复它,但它会运行相同的代码两次,因此,如果成员很昂贵,这将不是明智的做法。然而,它是一个宏,因此在编译时运行,并且成员在mall list small==数百万个元素或更少的元素上运行得相当快,所以我想如果您阅读的引用与任何其他CL代码一样好,那就不重要了。对于其他类型的口齿不清者,另一种可能更具可读性的方法是:
(let ((found (member x bindings :key #'cadr)))
(tree-leaves body found (caar found)))
你是说递归,还是我只是错过了自我引用?@BlackPlanet我猜他指的是1。你能举例说明用法吗?对一个例子进行宏观扩展会更好。let binding transform和tree leaf的定义也可能有助于理解此处的意图?在某种程度上,它类似于将同一事物写两次,因为它也会运行两次。对吗?@EuAndré对。这只是书面上的压缩,而不是执行上的压缩。