all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* Recognizing declares in lambdas
@ 2024-07-30 21:29 Thuna
  2024-08-01 23:25 ` Recognizing declares in lambdas - declarations embedded in functions Thuna
  0 siblings, 1 reply; 2+ messages in thread
From: Thuna @ 2024-07-30 21:29 UTC (permalink / raw)
  To: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1312 bytes --]

Right now `declare' is essentially a hack; it only works because `def*'
forms recognize and remove it from the lambda which is then passed to
defalias.  And due to the unfortunate order of `declare' and
`interactive' forms in defun it is not possible to simply put the
`declare' into the lambda, as that would break any following
`interactive' forms.

This alone is a simple fix - I have attached a PoC patch - but the
question of what to actually do with those declarations is one that is
very wide-reaching and I cannot answer that, much less implement it, on
my own.

One possibility which I am thinking of would be to add another slot to
closures which holds these declare forms and to make function-get and
function-put refer to these slots instead, and while a lot of
declarations would work out of the box with this setup, stuff like gv's
declarations will not.

A solution might be to have `def*' apply and remove the declarations
they recognize in their `*-declarations-alist' and send the rest over to
the `lambda', which *would* conceptually work, but as I have not
actually implemented it might contain pitfalls that I cannot predict at
the moment.

I would like to get some opinions on this.  I think that at the very
least lambdas should recognize declares even if they don't do anything
with it.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Patch which makes lambdas recognize declare forms --]
[-- Type: text/x-patch, Size: 3477 bytes --]

From d22e1d7c03df30208556904ec7cbf3c1210fa502 Mon Sep 17 00:00:00 2001
From: Thuna <thuna.cing@gmail.com>
Date: Tue, 30 Jul 2024 02:33:49 +0200
Subject: [PATCH] Recognize declares in lambdas

---
 lisp/subr.el | 14 ++------------
 src/eval.c   | 19 ++++++++++++++++++-
 2 files changed, 20 insertions(+), 13 deletions(-)

diff --git a/lisp/subr.el b/lisp/subr.el
index fc847049332..481beeeecd8 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -378,7 +378,7 @@ dotimes
              ;; FIXME: This let often leads to "unused var" warnings.
              `((let ((,var ,counter)) ,@(cddr spec)))))))
 
-(defmacro declare (&rest specs)
+(defalias 'declare #'ignore
   "Do not evaluate any arguments, and return nil.
 If a `declare' form appears as the first form in the body of a
 `defun' or `defmacro' form, SPECS specifies various additional
@@ -388,17 +388,7 @@ declare
 The possible values of SPECS are specified by
 `defun-declarations-alist' and `macro-declarations-alist'.
 
-For more information, see info node `(elisp)Declare Form'."
-  ;; `declare' is handled directly by `defun/defmacro' rather than here.
-  ;; If we get here, it's because there's a `declare' somewhere not attached
-  ;; to a `defun/defmacro', i.e. a `declare' which doesn't do what it's
-  ;; intended to do.
-  (let ((form `(declare . ,specs)))  ;; FIXME: WIBNI we had &whole?
-    (macroexp-warn-and-return
-     (format-message "Stray `declare' form: %S" form)
-     ;; Make a "unique" harmless form to circumvent
-     ;; the cache in `macroexp-warn-and-return'.
-     `(progn ',form nil) nil 'compile-only)))
+For more information, see info node `(elisp)Declare Form'.")
 
 (defmacro ignore-errors (&rest body)
   "Execute BODY; if an error occurs, return nil.
diff --git a/src/eval.c b/src/eval.c
index 2161ab1e1ea..3ca3ce2328a 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -574,7 +574,7 @@ DEFUN ("function", Ffunction, Sfunction, 1, UNEVALLED, 0,
       Lisp_Object cdr = XCDR (quoted);
       Lisp_Object args = Fcar (cdr);
       cdr = Fcdr (cdr);
-      Lisp_Object docstring = Qnil, iform = Qnil;
+      Lisp_Object docstring = Qnil, decls = Qnil, iform = Qnil;
       if (CONSP (cdr))
         {
           docstring = XCAR (cdr);
@@ -596,6 +596,18 @@ DEFUN ("function", Ffunction, Sfunction, 1, UNEVALLED, 0,
           else
             docstring = Qnil;   /* Not a docstring after all.  */
         }
+      if (CONSP (cdr))
+	{
+	  decls = XCAR (cdr);
+	  if (CONSP (decls)
+	      && EQ (Qdeclare, XCAR (decls)))
+	    {
+	      decls = XCDR (decls);
+	      cdr = XCDR (cdr);
+	    }
+	  else
+	    decls = Qnil;	/* Not a declare-form after all.  */
+	}
       if (CONSP (cdr))
         {
           iform = XCAR (cdr);
@@ -605,6 +617,10 @@ DEFUN ("function", Ffunction, Sfunction, 1, UNEVALLED, 0,
           else
             iform = Qnil;   /* Not an interactive-form after all.  */
         }
+      /* FIXME: Temporary patch since we're not handling declare forms
+         in lambdas yet. */
+      if (!NILP (decls))       /* FIXME: What about an empty declare? */
+	cdr = Fcons (Fcons (Qdeclare, decls), cdr);
       if (NILP (cdr))
         cdr = Fcons (Qnil, Qnil); /* Make sure the body is never empty! */
 
@@ -4334,6 +4350,7 @@ syms_of_eval (void)
   DEFSYM (Qexit, "exit");
 
   DEFSYM (Qinteractive, "interactive");
+  DEFSYM (Qdeclare, "declare");
   DEFSYM (Qcommandp, "commandp");
   DEFSYM (Qand_rest, "&rest");
   DEFSYM (Qand_optional, "&optional");
-- 
2.44.2


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

end of thread, other threads:[~2024-08-01 23:25 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-07-30 21:29 Recognizing declares in lambdas Thuna
2024-08-01 23:25 ` Recognizing declares in lambdas - declarations embedded in functions Thuna

Code repositories for project(s) associated with this external index

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

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.