emacs-bug-tracker
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#50834: closed (Feature request: cl-remove-method (prototyped) and bu


From: GNU bug Tracking System
Subject: bug#50834: closed (Feature request: cl-remove-method (prototyped) and buttons for it)
Date: Sun, 03 Sep 2023 08:39:02 +0000

Your message dated Sun, 3 Sep 2023 01:38:41 -0700
with message-id 
<CADwFkmkkheqRp5UZgzU5TQ-km0Ybh0-zaPxWaR41dNWMv9+Brg@mail.gmail.com>
and subject line Re: bug#50834: Feature request: cl-remove-method (prototyped) 
and buttons for it
has caused the debbugs.gnu.org bug report #50834,
regarding Feature request: cl-remove-method (prototyped) and buttons for it
to be marked as done.

(If you believe you have received this mail in error, please contact
help-debbugs@gnu.org.)


-- 
50834: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=50834
GNU Bug Tracking System
Contact help-debbugs@gnu.org with problems
--- Begin Message --- Subject: Feature request: cl-remove-method (prototyped) and buttons for it Date: Mon, 27 Sep 2021 01:09:00 +0000
I don't use CLOS or EIEIO very often but when I do, I remove methods all
the time.  I thus think it's a very important part of CLOS worflow.
SLIME inspector (for Common Lisp) offers buttons that remove methods on
the gf's page, e.g.:

Name: PRINT-OBJECT
Arguments: (SB-PCL::OBJECT STREAM)
Method class: #<STANDARD-CLASS COMMON-LISP:STANDARD-METHOD>
Method combination: #<SB-PCL::STANDARD-METHOD-COMBINATION STANDARD () 
{10002158A3}>
Methods: 
(TRACE-ENTRY T) [remove method]
(UNREADABLE-RESULT T) [remove method]
(CHANNEL T) [remove method]
(CONNECTION T) [remove method]
...

[remove method] are buttons.  Sadly, Elisp doesn't have an inspector but
I've heard of one effort github.com/mmontone/emacs-inspector and anyway,
these buttons would be appropriate in any displayed list of methods,
including the list currently shown in *Help* buffer for the gf.

Example:

Implementations:

[remove] :around (object stream) in ‘cl-print.el’.

Undocumented

[remove] ((object string) stream) in ‘cl-print.el’.

...


Recently it became necessary to use cl-remove-method in a library code
so I tried to write it.

The following seems to work but I'm very far from being confident about
it.  Also, methods are cached in lambdas returned by lambdas returned by
cl--generic-get-dispatcher, and I haven't yet figured out a way to get
them out of there; I'm also not sure if they should be removed manually,
or the tables will just get GC'ed given the proposed implementation of
cl-remove-method as is.

>From 50dc42ce1ea504657ccdcf85e9c71a2f27109610 Mon Sep 17 00:00:00 2001
From: akater <nuclearspace@gmail.com>
Date: Sun, 26 Sep 2021 21:33:46 +0000
Subject: [PATCH] Add cl-remove-method

---
 lisp/emacs-lisp/cl-generic.el | 31 ++++++++++++++++++++++++++++++-
 1 file changed, 30 insertions(+), 1 deletion(-)

diff --git a/lisp/emacs-lisp/cl-generic.el b/lisp/emacs-lisp/cl-generic.el
index 1640975b84..7d5c8ddc0d 100644
--- a/lisp/emacs-lisp/cl-generic.el
+++ b/lisp/emacs-lisp/cl-generic.el
@@ -98,7 +98,7 @@
 ;; usually be simplified, or even completely skipped.
 
 (eval-when-compile (require 'cl-lib))
-(eval-when-compile (require 'cl-macs))  ;For cl--find-class.
+(eval-when-compile (require 'cl-macs))  ;For cl--find-class, cl-loop
 (eval-when-compile (require 'pcase))
 
 (cl-defstruct (cl--generic-generalizer
@@ -1255,6 +1255,35 @@ defun cl--generic-struct-specializers (tag &rest _)
 (cl--generic-prefill-dispatchers 0 integer)
 (cl--generic-prefill-dispatchers 0 cl--generic-generalizer integer)
 
+(cl-defmethod cl-remove-method ((generic-function cl--generic) method)
+  "An equivalent of Common Lisp's method for remove-method
+specialized on
+(COMMON-LISP:STANDARD-GENERIC-FUNCTION COMMON-LISP:METHOD)."
+  (setf (cl--generic-method-table generic-function)
+        ;; delq could cause bugs, let's see if it does
+        (delq method (cl--generic-method-table generic-function)))
+
+  (cl-loop for k being hash-key in cl--generic-combined-method-memoization
+           when (and (eq generic-function (car k))
+                     (memq method (cdr k)))
+           do (remhash k cl--generic-combined-method-memoization))
+
+  ;; It might make sense to move this
+  (defalias (cl--generic-name generic-function)
+    (cl--generic-make-function generic-function))
+  ;; to an :after method
+  ;; but it's not even clear to me whether
+  ;; having such :after method would be compatible with Common Lisp standard.
+  generic-function)
+
+(cl-defmethod cl-remove-method ((generic-function symbol) method)
+  "For Common Lisp compatibility in Elisp.
+
+Namely, (cl-remove-method #'f ..) should work correctly but #'f returns symbol 
in Elisp."
+  (if-let ((gf (cl--generic generic-function)))
+      (cl-remove-method gf method)
+    (error "No generic function named %s" generic-function)))
+
 ;;; Dispatch on major mode.
 
 ;; Two parts:
-- 
2.32.0


--- End Message ---
--- Begin Message --- Subject: Re: bug#50834: Feature request: cl-remove-method (prototyped) and buttons for it Date: Sun, 3 Sep 2023 01:38:41 -0700
Lars Ingebrigtsen <larsi@gnus.org> writes:

> Stefan Monnier <monnier@iro.umontreal.ca> writes:
>
>> Not much to say, except:
>>
>>> +  (cl-loop for k being hash-key in cl--generic-combined-method-memoization
>>> +           when (and (eq generic-function (car k))
>>> +                     (memq method (cdr k)))
>>> +           do (remhash k cl--generic-combined-method-memoization))
>>
>> I don't see why we'd need this.
>>
>> This is a cache that tries to speed up the construction of combined
>> methods, whereas in `cl-remove-method` we should only need to flush the
>> cache that maps tags to their corresponding combined methods and this is
>> done implicitly by `cl--generic-make-function` (which returns a new
>> function with a branch new fresh cache).
>
> Akater, do you have any comments (or an amended patch)?

More information was requested, but none was given within 10 months, so
I'm closing this bug.  If this is still an issue, please reply to this
email (use "Reply to all" in your email client) and we can reopen the
bug report.


--- End Message ---

reply via email to

[Prev in Thread] Current Thread [Next in Thread]