Subject: Re: bug#8711: 24.0.50; binding _ to unused values with lexical-binding

From: Stefan Monnier <[email-masked]>
Date: Tue, 24 May 2011 09:42:31 -0300

> ;; -*- lexical-binding: t -*-
> (defun foo (x) (destructuring-bind (y &rest _) x y))

> x.el:2:1:Warning: variable `_' not left unused

Ah, yes, this one.  This is because CL's destructuring-bind expands the
above to something like

  (let ((_ x)
        (y (prog1 (car _) (setq _ (cdr _)))))
   y)

where _ is indeed not left unused.  It also means that a closure that
for (destructuring-bind (y &rest z) x (lambda () z)) the closure
captures a mutated var which is something more costly (the var needs to
be put inside a cons cell, leading to code along the lines of:

  (let ((z (list x))
        (y (prog1 (car (car z)) (setcar z (cdr (car z))))))
   (make-closure () [z] (car z)))

Again this is a side-effect of `let' being costly in dynbind code.
For lexbind code it would be better for destructuring-bind to use an
additional internal var:

  (let ((<internal> x)
        (y (prog1 (car <internal>) (setq <internal> (cdr <internal>))))
        (_ <internal>))
    y)

Which would not generate any warning and would lead to more efficient
code when the &rest var is captured by a closure.

        Stefan