EuAndreh
EuAndreh

Reputation: 578

What does this self referencing code do?

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

Answers (1)

Sylwester
Sylwester

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

Related Questions