From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Stefan Monnier via "Bug reports for GNU Emacs, the Swiss army knife of text editors" Newsgroups: gmane.emacs.bugs Subject: bug#54802: OClosure: Make `interactive-form` a generic function Date: Thu, 14 Apr 2022 14:34:24 -0400 Message-ID: References: <87r161to4p.fsf@yahoo.com> Reply-To: Stefan Monnier Mime-Version: 1.0 Content-Type: text/plain Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="5298"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/29.0.50 (gnu/linux) Cc: 54802@debbugs.gnu.org To: Po Lu Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Thu Apr 14 20:38:56 2022 Return-path: Envelope-to: geb-bug-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 1nf4Mp-00017c-Gf for geb-bug-gnu-emacs@m.gmane-mx.org; Thu, 14 Apr 2022 20:38:55 +0200 Original-Received: from localhost ([::1]:39858 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nf4Mo-0002Kf-57 for geb-bug-gnu-emacs@m.gmane-mx.org; Thu, 14 Apr 2022 14:38:54 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:37126) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nf4J4-0000Vw-T6 for bug-gnu-emacs@gnu.org; Thu, 14 Apr 2022 14:35:04 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:35236) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1nf4J4-0002zL-H2 for bug-gnu-emacs@gnu.org; Thu, 14 Apr 2022 14:35:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1nf4J4-0007xG-DB for bug-gnu-emacs@gnu.org; Thu, 14 Apr 2022 14:35:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Stefan Monnier Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Thu, 14 Apr 2022 18:35:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 54802 X-GNU-PR-Package: emacs Original-Received: via spool by 54802-submit@debbugs.gnu.org id=B54802.164996128430547 (code B ref 54802); Thu, 14 Apr 2022 18:35:02 +0000 Original-Received: (at 54802) by debbugs.gnu.org; 14 Apr 2022 18:34:44 +0000 Original-Received: from localhost ([127.0.0.1]:57365 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1nf4Il-0007wd-OP for submit@debbugs.gnu.org; Thu, 14 Apr 2022 14:34:44 -0400 Original-Received: from mailscanner.iro.umontreal.ca ([132.204.25.50]:46790) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1nf4Ik-0007wL-9S for 54802@debbugs.gnu.org; Thu, 14 Apr 2022 14:34:42 -0400 Original-Received: from pmg2.iro.umontreal.ca (localhost.localdomain [127.0.0.1]) by pmg2.iro.umontreal.ca (Proxmox) with ESMTP id 761E88062B; Thu, 14 Apr 2022 14:34:36 -0400 (EDT) Original-Received: from mail01.iro.umontreal.ca (unknown [172.31.2.1]) by pmg2.iro.umontreal.ca (Proxmox) with ESMTP id BC21680570; Thu, 14 Apr 2022 14:34:34 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=iro.umontreal.ca; s=mail; t=1649961274; bh=tXAB/9wriBE9cQLrkWhtM//MhW3g0B/hgQuVzZ9fbNo=; h=From:To:Cc:Subject:References:Date:In-Reply-To:From; b=Y1qM0IrZWFCb0N6IOThryTBuWdTOR/100RpHBIAJR5Cg2oaX5V/Mm4doo8DyvMQko W/pbyV2fvmMMtgkC8PfwVPdcmjdy5pbXdO60QFUZCPQ4n5rNWibFB3yb5xsSQ1+P3b PXQdFy9iVDz+Cxvs8KlbheqPo0iO27uskLUubvaPezIlWF9q056Mr4L5dvkeSuwXCJ dvzC5arrmBJBrn4/QSUJZ4LCtjsRYkIjiECAaCrFW0xrXlRPngIohpNen+R9ffAAuZ Ux052bP4IluMdj+N8Z/H4lX6NhgcZoGkmFEXy+djP6P1bpjxY705izkNWjZm6UmdgN Jnc6GceLVm+Kg== Original-Received: from alfajor (unknown [45.72.221.51]) by mail01.iro.umontreal.ca (Postfix) with ESMTPSA id 8BE9C1201A4; Thu, 14 Apr 2022 14:34:34 -0400 (EDT) In-Reply-To: <87r161to4p.fsf@yahoo.com> (Po Lu's message of "Wed, 13 Apr 2022 15:53:58 +0800") X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:229896 Archived-At: > Calling `interactive-form' in a loop is also fairly common. Do you have actual examples in some existing package? > For example, I wrote some code a while back to list commands which > operate on the region, which involves running this on each interned > atom: > > (defun region-command-p (command) > "Test if COMMAND, a symbol, is a command that accepts a region." > (and (commandp command) > (equal (cadr (interactive-form command)) "r"))) Interesting. I just tested this in an `all-completions` loop and my patch makes it run a factor of 2 slower (it went from ~30ms to ~60ms to enumerate the 141 commands that matched). There are some mitigating circumstances, tho: - The first call to this code takes a lot of time (~6s) because it loads a crapload of packages (every package with a registered autoloaded command). - It's very brittle since it won't find those commands that have interactive specs like "r\np" or where it's not a string (like `kill-region` and many others, actually there are regularly more, e.g. to make them obey `use-region-p`). - That loop signaled an error because of an erroneous autoload in `gnus.el` (it's now fixed in `master`), so your code probably did not do that. [ Amusingly, I also tried the loop after removing the `commandp` call (which is arguably unnecessary and could even slow down the loop) but this bumped into even more errors because we then try to load even the non-interactive functions. ] > I'm sure a 3x slowdown would be noticeable, so why does this have to be > a generic function? Making a generic function is the "natural" choice in terms of the semantics of the function (which is implemented as a sequence of tests to dispatch to some implementation-specific alternative). I could change `interactive-form` along the same lines as what I've done with `function-documentation`, i.e. only delegate to a generic function when it looks like an OClosure. That would significantly reduce the performance impact, probably to negligible levels, but semantically the only difference between `interactive-form` and that new `generic-interactive-form` is that one is generic and the other isn't, so it's rather ugly. I've never seen the kind of tight loop you suggest, which is why I have the impression that we can afford to just make `interactive-form` into a generic function, which is a simpler and cleaner API. > Why can't we have `interactive-form' return some > field of a given OClosure object instead? One reason is that for the case of advice, I'd much rather compute the interactive spec lazily (when the command is called) rather than when the advice is built. Another reason is that there is no dedicated "oclosure slot" for an interactive-spec. In theory we could use the byte-code object's slot for that, but making it computable (as needed for bug#51695 and for advice) would require significant changes to cconv.el and bytecomp.el (and to make it not too inconvenient to use in `advice.el` it'd additionally require extending the syntax of `interactive`). We could add a dedicated "oclosure slot" for the interactive-spec, but it'd likely be rather ugly, since that would need to be accessed from the C in `cmds.c` but would require testing the type of the OClosure first and that would have to be written in ELisp since it depends on how OClosure types are represented which itself depends on `cl-defstruct`, etc... So if we want to go in this direction it'd be simpler and cleaner to keep the C implementation of `interactive-form` and have it delegate to a new `generic-interactive-form` when it finds an OClosure. Stefan