unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Adding a DECLARE spec equivalent to DECLARE-FUNCTION
@ 2024-03-03 19:17 Adam Porter
  2024-03-16 10:04 ` Basil L. Contovounesios
  0 siblings, 1 reply; 3+ messages in thread
From: Adam Porter @ 2024-03-03 19:17 UTC (permalink / raw)
  To: emacs-devel

[See <https://debbugs.gnu.org/cgi/bugreport.cgi?bug=69521>.]

Hi,

In light of [this thread], this seems like a good time to propose this
idea: to enhance the `declare' form with a `function' spec equivalent to
the top-level `declare-function' form.  This allows keeping the
declaration inside the function that makes it necessary, which has a few
advantages:

1. It clearly indicates which function makes the declaration necessary
    (i.e. which function contains calls to the function in another
    library).
2. If the function is moved to another file, the declaration moves with
    it.
3. If the function is removed, the declaration is removed with it.
4. It reduces the number of top-level forms.

Also, it seems like a natural fit, i.e. `declare-function' to `(declare
(function ...))'.

As an experiment, I implemented this in [Ement] about 10 months ago, and
I've neither seen nor heard of any problems with it.  Here's the code
that implements it:

┌────
│ (eval-and-compile
│   (defun ement--byte-run--declare-function (_name _args &rest values)
│     "Return a `declare-function' form with VALUES.
│ Allows the use of a form like:
│
│   (declare (function FN FILE ...))
│
│ inside of a function definition, effectively keeping its
│ `declare-function' form inside the function definition, ensuring
│ that stray such forms don't remain if the function is removed."
│     `(declare-function ,@values))
│
│   (cl-pushnew '(function ement--byte-run--declare-function)
defun-declarations-alist :test #'equal)
│   (cl-pushnew '(function ement--byte-run--declare-function)
macro-declarations-alist :test #'equal))
└────

In use, it looks like this:

┌────
│ (defun ement-notifications--make (notification)
│   "Return an `ement-notification' struct for NOTIFICATION.
│ NOTIFICATION is an alist representing a notification returned
│ from the \"/notifications\" endpoint.  The notification's event
│ is passed through `ement--make-event'."
│   (declare (function ement--make-event "ement"))
│   (pcase-let (((map room_id _actions _ts event read) notification))
│     (make-ement-notification :room-id room_id :readp read
│                              :event (ement--make-event event))))
└────

Would this be an acceptable addition to Emacs Lisp?  If so, I'd be glad
to prepare a patch.

Thanks, Adam


[this thread]
<https://lists.gnu.org/archive/html/emacs-devel/2024-03/msg00057.html>

[Ement] <https://elpa.gnu.org/packages/ement.html>



^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Adding a DECLARE spec equivalent to DECLARE-FUNCTION
  2024-03-03 19:17 Adding a DECLARE spec equivalent to DECLARE-FUNCTION Adam Porter
@ 2024-03-16 10:04 ` Basil L. Contovounesios
  2024-03-17  4:09   ` Adam Porter
  0 siblings, 1 reply; 3+ messages in thread
From: Basil L. Contovounesios @ 2024-03-16 10:04 UTC (permalink / raw)
  To: Adam Porter; +Cc: emacs-devel

Adam Porter [2024-03-03 13:17 -0600] wrote:

> In light of [this thread], this seems like a good time to propose this
> idea: to enhance the `declare' form with a `function' spec equivalent to
> the top-level `declare-function' form.  This allows keeping the
> declaration inside the function that makes it necessary, which has a few
> advantages:
>
> 1. It clearly indicates which function makes the declaration necessary
>    (i.e. which function contains calls to the function in another
>    library).
> 2. If the function is moved to another file, the declaration moves with
>    it.
> 3. If the function is removed, the declaration is removed with it.
> 4. It reduces the number of top-level forms.
>
> Also, it seems like a natural fit, i.e. `declare-function' to `(declare
> (function ...))'.
>
> Would this be an acceptable addition to Emacs Lisp?

FWIW, my vote is against such a declare spec.  Compared to other declare
specs, this one introduces the tightest coupling between a function's
property declarations and the function's body, i.e. its implementation
details.  Knowing that, at a particular point in the body, a given
function will be defined, is a local property of that particular
expression, not a global property of the containing function.

My vote is for instead teaching the compiler to treat declare-function
more like it treats defvar, in that the effect of declare-function
should be made local to the current lexical scope.  [It is already
possible to write this way, and I've been known to, but sadly the effect
is global.]  This wish has been raised and agreed on here (at least in
passing) before.

This would reap all the benefits of points 1-4, as well as an additional
one: that declare-function is lexically closer to the implementation
through which the need for the declaration arises.  I think a
declaration at the top of a function is more likely to be forgotten and
become stale as the implementation changes.

-- 
Basil



^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Adding a DECLARE spec equivalent to DECLARE-FUNCTION
  2024-03-16 10:04 ` Basil L. Contovounesios
@ 2024-03-17  4:09   ` Adam Porter
  0 siblings, 0 replies; 3+ messages in thread
From: Adam Porter @ 2024-03-17  4:09 UTC (permalink / raw)
  To: Basil L. Contovounesios; +Cc: emacs-devel

Hi Basil,

Thanks for your thoughtful reply.

On 3/16/24 05:04, Basil L. Contovounesios wrote:

> My vote is for instead teaching the compiler to treat declare-function
> more like it treats defvar, in that the effect of declare-function
> should be made local to the current lexical scope.  [It is already
> possible to write this way, and I've been known to, but sadly the effect
> is global.]  This wish has been raised and agreed on here (at least in
> passing) before.
> 
> This would reap all the benefits of points 1-4, as well as an additional
> one: that declare-function is lexically closer to the implementation
> through which the need for the declaration arises.  I think a
> declaration at the top of a function is more likely to be forgotten and
> become stale as the implementation changes.

You raise some good points.  I would be happy with that as well.

--Adam



^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2024-03-17  4:09 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-03-03 19:17 Adding a DECLARE spec equivalent to DECLARE-FUNCTION Adam Porter
2024-03-16 10:04 ` Basil L. Contovounesios
2024-03-17  4:09   ` Adam Porter

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).