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

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

bug#30202: 27.0.50; Code refactoring on assq-delete-all assoc-delete-all


From: Tino Calancha
Subject: bug#30202: 27.0.50; Code refactoring on assq-delete-all assoc-delete-all
Date: Tue, 23 Jan 2018 00:04:24 +0900 (JST)
User-agent: Alpine 2.20 (DEB 67 2015-01-07)



On Mon, 22 Jan 2018, Stefan Monnier wrote:

yesterday was added (how about to announce it in NEWS file?)
the new function `assoc-delete-all', which is pretty much
the same as `assq-delete-all' with `equal' instead of `eq'.
How do you think below patch?

How 'bout defining

(defun assoc-delete-all (key alist &optional test)
 (unless test (setq test #'equal))
 ...)
Yes, I prefer this way.  Thank you.
Updated patch below.

IIUC, the byte compiler will carry the substitution
(funcall function foo bar)
into
(function foo bar)
so that compile code won't suffer the funcall overhead, right?

IIRC both forms result in the same bytecode except that the longer form
will not benefit from inlining and/or the use of specialized bytecodes
(e.g. when `foo` is `equal`).
Here I tend to prefer to avoid the duplication of the similar code; in
case that the gain of performance result critical, and considering
that the functions are very short, then it might be OK repeat ourselves.

--8<-----------------------------cut here---------------start------------->8---
commit 9ecce395b1f2def081187d3e430d0cb82af8ba01
Author: tino calancha <tino.calancha@gmail.com>
Date:   Mon Jan 22 23:53:27 2018 +0900

    Code refactoring

    * lisp/subr.el (assoc-delete-all): Add optional arg TEST.
    (assq-delete-all): Use assoc-delete-all.

diff --git a/lisp/subr.el b/lisp/subr.el
index 092850a44d..e7a0ffc5be 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -705,17 +705,19 @@ member-ignore-case
     (setq list (cdr list)))
   list)

-(defun assoc-delete-all (key alist)
-  "Delete from ALIST all elements whose car is `equal' to KEY.
+(defun assoc-delete-all (key alist &optional test)
+  "Delete from ALIST all elements whose car is KEY.
+Compare keys with TEST.  Defaults to `equal'.
 Return the modified alist.
 Elements of ALIST that are not conses are ignored."
+  (unless test (setq test #'equal))
   (while (and (consp (car alist))
-             (equal (car (car alist)) key))
+             (funcall test (caar alist) key))
     (setq alist (cdr alist)))
   (let ((tail alist) tail-cdr)
     (while (setq tail-cdr (cdr tail))
       (if (and (consp (car tail-cdr))
-              (equal (car (car tail-cdr)) key))
+              (funcall test (caar tail-cdr) key))
          (setcdr tail (cdr tail-cdr))
        (setq tail tail-cdr))))
   alist)
@@ -724,16 +726,7 @@ assq-delete-all
   "Delete from ALIST all elements whose car is `eq' to KEY.
 Return the modified alist.
 Elements of ALIST that are not conses are ignored."
-  (while (and (consp (car alist))
-             (eq (car (car alist)) key))
-    (setq alist (cdr alist)))
-  (let ((tail alist) tail-cdr)
-    (while (setq tail-cdr (cdr tail))
-      (if (and (consp (car tail-cdr))
-              (eq (car (car tail-cdr)) key))
-         (setcdr tail (cdr tail-cdr))
-       (setq tail tail-cdr))))
-  alist)
+  (assoc-delete-all key alist #'eq))

 (defun rassq-delete-all (value alist)
   "Delete from ALIST all elements whose cdr is `eq' to VALUE.
--8<-----------------------------cut here---------------end--------------->8---





reply via email to

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