Reputation: 578
What is this self reference for?
Could it be written in any other way?
Is there any advantage?
(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#)))))
Upvotes: 2
Views: 110
Reputation: 48775
It's just a way of reusing structure somewhere else. In the macro you have:
(tree-leaves body
#1=(member x bindings :key #'cadr)
(caar #1#))
Which is just a fancy way of writing:
(tree-leaves body
(member x bindings :key #'cadr)
(caar (member x bindings :key #'cadr)))
On the positive side if you correct a bug in the member
form you'll fix it both places, but it's runs the same code twice so if member
was expensive this wouldn't be the wise way to do it. However it is a macro, thus run at compile time, and member
is fairly fast on mall lists (small == millions of elements or below) so I guess it won't matter if you read the references just as good as any other CL code. An alternative and perhaps more readable for other kind of lispers would be:
(let ((found (member x bindings :key #'cadr)))
(tree-leaves body found (caar found)))
Upvotes: 4