Subject: bug#76294: closed (Re: bug#76294: `(cl-proclaim (inline foo))` vs `(defsubst foo ...)`)

From: [email-masked] (GNU bug Tracking System)
Date: Fri, 14 Feb 2025 23:51:02 +0000

Your bug report

#76294: `(cl-proclaim (inline foo))` vs `(defsubst foo ...)`

which was filed against the emacs package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
76294: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=76294
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#76294: `(cl-proclaim (inline foo))` vs `(defsubst foo ...)`
From: Stefan Kangas <[email-masked]>
To: Stefan Monnier <[email-masked]>
Cc: [email-masked],João Távora <[email-masked]>
Date: Fri, 14 Feb 2025 23:50:29 +0000
List-Id: <debbugs-submit.debbugs.gnu.org>

Stefan Monnier <[email-masked]> writes:

>> May I ask what is the value proposition of
>>
>>     (defun foo () ...)
>>     (cl-proclaim '(inline foo))
>>
>> over
>>
>>     (defsubst foo () ...)
>>
>> in Emacs Lisp code?
>
> I never dared to touch this because I know I'm biased against those
> thingies.  IOW, I'd be happy to deprecate such usage.  🙂

I probably won't get into deprecating it completely, to be honest.  Not
right now, at any rate.

>> I'm asking because running into this in cl-lib.el made me start to
>> consider the below patch.
>
> Looks good to me.  I suspect the reason behind the current code might be
> that `defsubst` was introduced after cl.el got (and used) `proclaim`.

Makes sense, thanks!

I think it's a good enough argument that the implementation itself
should make sense from an Emacs Lisp perspective, so I installed the
patch.  AFAICT, there is now exactly one use of `cl-proclaim` in all of
Emacs and GNU ELPA.  I didn't check NonGNU ELPA.

If anyone has anything relevant to add for posterity, please do.

Subject: `(cl-proclaim (inline foo))` vs `(defsubst foo ...)`
From: Stefan Kangas <[email-masked]>
To: [email-masked]
Date: Fri, 14 Feb 2025 22:29:47 +0000
List-Id: <debbugs-submit.debbugs.gnu.org>

Severity: wishlist

May I ask what is the value proposition of

    (defun foo () ...)
    (cl-proclaim '(inline foo))

over

    (defsubst foo () ...)

in Emacs Lisp code?

I assume that it won't be much help when porting code from CL, so I
guess it's just to make ELisp feel more homely to CL programmers?

If it is intended as documentation of cl-proclaim itself, I propose
improving the cl-proclaim documentation instead.  The docstring is
rather on the brief side, shall we say.

I'm asking because running into this in cl-lib.el made me start to
consider the below patch.  It's possible that I'm just the wrong person
to be digging around in cl-lib.el, though...
From 87573e46320fd9c2b8f183ef311bf6393155c2c4 Mon Sep 17 00:00:00 2001
From: Stefan Kangas <[email-masked]>
Date: Fri, 14 Feb 2025 23:18:56 +0100
Subject: [PATCH] Avoid cl-proclaim

---
 lisp/emacs-lisp/cl-extra.el | 10 +++++-----
 lisp/emacs-lisp/cl-lib.el   |  2 +-
 lisp/emacs-lisp/cl-macs.el  |  4 ----
 3 files changed, 6 insertions(+), 10 deletions(-)

diff --git a/lisp/emacs-lisp/cl-extra.el b/lisp/emacs-lisp/cl-extra.el
index 62e12217e0d..09470457d93 100644
--- a/lisp/emacs-lisp/cl-extra.el
+++ b/lisp/emacs-lisp/cl-extra.el
@@ -127,7 +127,7 @@ cl--mapcar-many
 	(and acc (nreverse cl-res)))))
 
 ;;;###autoload
-(defun cl-map (cl-type cl-func cl-seq &rest cl-rest)
+(defsubst cl-map (cl-type cl-func cl-seq &rest cl-rest)
   "Map a FUNCTION across one or more SEQUENCEs, returning a sequence.
 TYPE is the sequence type to return.
 \n(fn TYPE FUNCTION SEQUENCE...)"
@@ -239,14 +239,14 @@ cl-every
     (null cl-seq)))
 
 ;;;###autoload
-(defun cl-notany (cl-pred cl-seq &rest cl-rest)
+(defsubst cl-notany (cl-pred cl-seq &rest cl-rest)
   "Return true if PREDICATE is false of every element of SEQ or SEQs.
 \n(fn PREDICATE SEQ...)"
   (declare (important-return-value t))
   (not (apply #'cl-some cl-pred cl-seq cl-rest)))
 
 ;;;###autoload
-(defun cl-notevery (cl-pred cl-seq &rest cl-rest)
+(defsubst cl-notevery (cl-pred cl-seq &rest cl-rest)
   "Return true if PREDICATE is false of some element of SEQ or SEQs.
 \n(fn PREDICATE SEQ...)"
   (declare (important-return-value t))
@@ -589,13 +589,13 @@ cl-concatenate
 ;;; List functions.
 
 ;;;###autoload
-(defun cl-revappend (x y)
+(defsubst cl-revappend (x y)
   "Equivalent to (append (reverse X) Y)."
   (declare (side-effect-free t))
   (nconc (reverse x) y))
 
 ;;;###autoload
-(defun cl-nreconc (x y)
+(defsubst cl-nreconc (x y)
   "Equivalent to (nconc (nreverse X) Y)."
   (declare (important-return-value t))
   (nconc (nreverse x) y))
diff --git a/lisp/emacs-lisp/cl-lib.el b/lisp/emacs-lisp/cl-lib.el
index 883a13e3244..dba01b28325 100644
--- a/lisp/emacs-lisp/cl-lib.el
+++ b/lisp/emacs-lisp/cl-lib.el
@@ -535,7 +535,7 @@ cl--do-subst
 	       cl-tree (cons a d))))
 	(t cl-tree)))
 
-(defun cl-acons (key value alist)
+(defsubst cl-acons (key value alist)
   "Add KEY and VALUE to ALIST.
 Return a new list with (cons KEY VALUE) as car and ALIST as cdr."
   (declare (side-effect-free error-free))
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el
index 44fe67b6c85..caaffcf19be 100644
--- a/lisp/emacs-lisp/cl-macs.el
+++ b/lisp/emacs-lisp/cl-macs.el
@@ -3725,10 +3725,6 @@ cl--compiler-macro-get
       `(cl-getf (symbol-plist ,sym) ,prop ,def)
     `(get ,sym ,prop)))
 
-;;; Things that are inline.
-(cl-proclaim '(inline cl-acons cl-map cl-notany cl-notevery cl-revappend
-               cl-nreconc))
-
 ;;; Types and assertions.
 
 ;;;###autoload
-- 
2.48.1