这个自引用代码有什么作用?

时间:2014-12-16 20:26:29

标签: 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))
        bindings))
    `(let (,@(mapcar #'list
                     (mapcar #'car bindings)
                     (mapcar #'caddr bindings)))
       ,@(tree-leaves
           body
           #1=(member x bindings :key #'cadr)
           (caar #1#)))))

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)))