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.devel Subject: Re: Gnus using lexical-binding Date: Sat, 30 Jan 2021 10:24:05 -0500 Message-ID: References: <83bld6aklb.fsf@gnu.org> Mime-Version: 1.0 Content-Type: text/plain Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="19505"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) Cc: Eli Zaretskii , emacs-devel@gnu.org To: Stefan Kangas Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Sat Jan 30 16:26:35 2021 Return-path: Envelope-to: ged-emacs-devel@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 1l5s8v-0004xF-Jf for ged-emacs-devel@m.gmane-mx.org; Sat, 30 Jan 2021 16:26:33 +0100 Original-Received: from localhost ([::1]:52550 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1l5s8u-0005fn-LR for ged-emacs-devel@m.gmane-mx.org; Sat, 30 Jan 2021 10:26:32 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:44448) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1l5s6m-0004ec-P2 for emacs-devel@gnu.org; Sat, 30 Jan 2021 10:24:22 -0500 Original-Received: from mailscanner.iro.umontreal.ca ([132.204.25.50]:44117) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1l5s6d-00022x-9M; Sat, 30 Jan 2021 10:24:19 -0500 Original-Received: from pmg1.iro.umontreal.ca (localhost.localdomain [127.0.0.1]) by pmg1.iro.umontreal.ca (Proxmox) with ESMTP id 63BC31006F2; Sat, 30 Jan 2021 10:24:09 -0500 (EST) Original-Received: from mail01.iro.umontreal.ca (unknown [172.31.2.1]) by pmg1.iro.umontreal.ca (Proxmox) with ESMTP id 554D710021D; Sat, 30 Jan 2021 10:24:07 -0500 (EST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=iro.umontreal.ca; s=mail; t=1612020247; bh=hb/jAyYlnVwtUp40mzZ6JFcVXWtdCP54/r3bYifokjg=; h=From:To:Cc:Subject:References:Date:In-Reply-To:From; b=iR9ILaAJU//3V5zk2ReOA4SACmDp/d+2U6/zm4T3IooHhbK09vVtU4+9yXZT2uIAy VIEDvGHdDBKilx80N+bTSnYyhDcnvppCNAsjVUfVhP4DRPdW+FZPWv+MRmGowRZI5W +1bpqVus4DnZ5nLWeg4hhHRAcEEWzzoL65Y98PfRycccMvJhbqF13VnpEg2orQEN4i bgDknHM39+MEUYcmKX+sovyFd9I7dCpW0xxIi8ZuQks82JyXLdmr9Ky+UxJuomYxaj 4MoTnx6fwE3Gn26EKEjWG6FCT8Nbq4IP8xO9gU6A7SgaLP1qS33rlDRd+JDoix8Q3o /to3f6kla5/sw== Original-Received: from alfajor (69-196-141-46.dsl.teksavvy.com [69.196.141.46]) by mail01.iro.umontreal.ca (Postfix) with ESMTPSA id 1E591120205; Sat, 30 Jan 2021 10:24:07 -0500 (EST) In-Reply-To: (Stefan Kangas's message of "Sat, 30 Jan 2021 05:43:13 -0800") Received-SPF: pass client-ip=132.204.25.50; envelope-from=monnier@iro.umontreal.ca; helo=mailscanner.iro.umontreal.ca X-Spam_score_int: -42 X-Spam_score: -4.3 X-Spam_bar: ---- X-Spam_report: (-4.3 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.io gmane.emacs.devel:263619 Archived-At: >> Btw, I think we could benefit from a detailed guide for how to convert >> a package to lexical-binding, enumerating the steps to take, tools and >> Emacs commands to use, possible problems and how to solve them, etc. >> Somewhere in admin/notes/, perhaps? > > What about `(elisp) Converting to Lexical Binding'? > > Should we perhaps just expand that? I'm sure third-party package > developers could also benefit from any details we would like to add. In terms of tools and commands, this section indeed describes what I use. I'm not sure how much further we want to go with that. The main other tool I use is my intuition and various heuristics: For the "unused var" warning, I can usually guess based on the name whether it should have a `defvar` or not: variables whose name has a "package prefix" should almost always have a `defvar` while those who have a short name should almost always use lexical scoping. Adding more `defvar`s than needed is largely harmless during conversion (it's arguably harmful in the long run, but that can be addresses later), so the main risk is for those variables with a non-prefixed name where we normally presume they can use lexical scoping but which may nevertheless require dynamic scoping. Furthermore, some of those cases can occur without triggering any warning from the byte-compiler because the var is not locally unused. This can happen typically with code like (let ((foo X) (bar Y)) ... (eval config-var) ...) where `config-var` is defined to hold an ELisp form which has access to variables `foo` and `bar`. If you're the package author or are a heavy user of the package there's a chance you know about it and can take it into account when performing the conversion, but otherwise it can be tricky to figure it out. The only way I know is to search for uses of `eval`, `symbol-value`, `intern`, and `set` (this list is sadly not exhaustive, e.g. some uses may occur via `run-hooks`) to try and find code that relies on access to variables via dynamic scoping and then examine each one to try and see which variables it may refer to, which is sometimes documented in comments or docstrings. This last part is tedious and rarely necessary, so I do it lazily, i.e. when something indicates that it's probably necessary (e.g. because of a regression found during testing, or because of some odd patterns in the "unused variables" warnings, e.g. when the same set of unused variable names appear a few times, tho sometimes these patterns are due to copy&paste as well). Stefan