From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Stefan Monnier Newsgroups: gmane.emacs.help Subject: Re: How to avoid compiler warning `unused lexical variable' for `dolist' or `dotimes'? Date: Fri, 08 Jan 2021 02:10:58 -0500 Message-ID: References: <87zh1kq97s.fsf@robertthorpeconsulting.com> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="29410"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) To: help-gnu-emacs@gnu.org Cancel-Lock: sha1:V6miPsP9uzAIC7glJILPz5GOIEw= Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane-mx.org@gnu.org Fri Jan 08 08:12:02 2021 Return-path: Envelope-to: geh-help-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kxlwH-0007Zg-NG for geh-help-gnu-emacs@m.gmane-mx.org; Fri, 08 Jan 2021 08:12:01 +0100 Original-Received: from localhost ([::1]:44024 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kxlwG-0003tU-Os for geh-help-gnu-emacs@m.gmane-mx.org; Fri, 08 Jan 2021 02:12:00 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:53388) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kxlvQ-0003su-PO for help-gnu-emacs@gnu.org; Fri, 08 Jan 2021 02:11:08 -0500 Original-Received: from ciao.gmane.io ([116.202.254.214]:39030) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kxlvO-0006Bl-NL for help-gnu-emacs@gnu.org; Fri, 08 Jan 2021 02:11:08 -0500 Original-Received: from list by ciao.gmane.io with local (Exim 4.92) (envelope-from ) id 1kxlvM-0006g7-PL for help-gnu-emacs@gnu.org; Fri, 08 Jan 2021 08:11:04 +0100 X-Injected-Via-Gmane: http://gmane.org/ Received-SPF: pass client-ip=116.202.254.214; envelope-from=geh-help-gnu-emacs@m.gmane-mx.org; helo=ciao.gmane.io X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, HEADER_FROM_DIFFERENT_DOMAINS=0.248, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Users list for the GNU Emacs text editor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "help-gnu-emacs" Xref: news.gmane.io gmane.emacs.help:127098 Archived-At: >> (dotimes (i length plist) >> (setf plist (plist-put plist (intern (elt columns i)) (elt values i)))))) > And here is the original warning: >> rcd-db.el:841:1: Warning: Unused lexical variable ā€˜iā€™ > Jean Louis actually is using the variable i, it's not unused. There are 2 places where `i` is introduced: - one around the body of the loop - another around the 3rd arg used as return value. To see it you need to macroexpand the `dotimes`: (dotimes (i length plist) (setf plist (plist-put plist (intern (elt columns i)) (elt values i)))) => (let ((--dotimes-limit-- length) (--dotimes-counter-- 0)) (while (< --dotimes-counter-- --dotimes-limit--) (let ((i --dotimes-counter--)) (setf plist (plist-put plist (intern (elt columns i)) (elt values i)))) (setq --dotimes-counter-- (1+ --dotimes-counter--))) (let ((i --dotimes-counter--)) plist)) Clearly, this is not the only way to define the macro, but it's a valid way (according to the Common Lisp definition, for example). Now you hopefully see on the last time that `i` is indeed defined but not used. This is the code which the compiler sees. You won't get this warning if you do: (dotimes (i length (progn (ignore i) plist)) (setf plist (plist-put plist (intern (elt columns i)) (elt values i)))) or (dotimes (i length) (setf plist (plist-put plist (intern (elt columns i)) (elt values i)))) plist I'm not trying to argue that the byte-compiler warning here is a feature, but in general the "unused var" byte compiler warnings are very useful (especially when converting code to `lexical-binding`) and while in this case it's kind of spurious it's very easy to change the code so as to avoid the warning (and the resulting code is also more efficient and arguably more readable for people not used to this 3rd arg of dotimes/dolist), so this is not a very compelling motivation to improve the warning machinery. There can be situations when using `pcase` where the byte-compiler will tend to emit similar warnings and these are more problematic because it can be hard to rewrite the code to avoid the warning. I haven't yet figured how to make it possible to avoid those warnings, so in the `pcase` macro I added extra hacks to try and avoid introducing bindings that aren't used, which basically silence those warnings, with the downside that you won't get the warning even in the case where it's really warranted. > You could argue that the warning should be "The three element version of > dotimes is discouraged". But I can't see how you can argue that the > warning is right, since i is used. The var-use analysis takes place after macro expansion. This is not specific to this warning, tho: all warnings suffer from false positives, almost by definition. If we knew for sure that the warning points to a real "bug" we could turn it into an error. Stefan