GNU bug report logs - #8711
24.0.50; binding _ to unused values with lexical-binding

Previous Next

Package: emacs;

Reported by: Helmut Eller <eller.helmut <at> gmail.com>

Date: Sat, 21 May 2011 18:45:02 UTC

Severity: minor

Found in versions 24.0.50, 26.0.50

Done: Lars Ingebrigtsen <larsi <at> gnus.org>

Bug is archived. No further changes may be made.

Full log


View this message in rfc822 format

From: Helmut Eller <eller.helmut <at> gmail.com>
To: 8711 <at> debbugs.gnu.org
Subject: bug#8711: 24.0.50; binding _ to unused values with lexical-binding
Date: Mon, 23 May 2011 22:16:22 +0200
* Stefan Monnier [2011-05-23 19:29] writes:

>> My problem is basically that I have a macro "destructure-case" that
>> expands to destructuring-bind, e.g.:
>
>> (destructure-case location
>>   ((:error _) nil)) ; do nothing
>
>> expands to
>
>> (ecase (car location)
>>   (:error (destructuring-bind (_) (cdr location)
>>             (ignore _)
>>             nil)))
>
>> The macro inserts the (ignore _) to suppress the "value returned from
>> (car --cl-rest--) is unused" warning.
>
> It can insert (ignore nil) instead which should have the same effect but
> without triggering the other warning with lexical-binding.

Indeed.  But I quickly run into another case where that doesn't help:

(defun foo (x) (destructuring-bind (y &rest _) x y))

>> There is also a somewhat related problem with loop:
>
>> ;; -*- lexical-binding: t -*-
>> (defun foo (alist) (loop for (_key . value) in alist collect value))
>
>> produces a "variable `_key' not left unused" warning.
>
> I think the same problem happens with dotimes/dolist using the old
> definition: the loop vars `key' and `value' are let-bound outside the
> loop and then setq'd at each loop iteration (it's this setq that causes
> them to be "not left unused").  This was OK for the dynamic scoping case
> because let-binding is significantly more costly than setq, but it is
> not right for the lexical scoping case where the cost of let is not
> higher than `setq' and where the semantic is actually then wrong:
> e.g. if you "collect (lambda () value)" the current code ends up
> returning a list of functions that all return the last `value', rather
> than a list of functions that each return one of the `values' in
> the alist.

The semantic of loop (in Common Lisp) allows both variants. So the
"portable" idiom is "collect (let ((value value)) (lambda () value))".

Helmut





This bug report was last modified 3 years and 11 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.