emacs-devel
[Top][All Lists]
Advanced

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

cl-macs: default indentation for all arglists with top-level &body


From: akater
Subject: cl-macs: default indentation for all arglists with top-level &body
Date: Sun, 11 Apr 2021 12:35:34 +0000


Attachment: signature.asc
Description: PGP signature

Attachment: 0001-cl-macs-default-indentation-for-all-arglists-with-to.patch
Description: cl-macs: indent via top-level &body

(This has been discussed earlier on the list --- more on this later.)

In Common Lisp, ~&body~ keyword is the same as ~&rest~ modulo
indentation:

#+begin_quote
&body is identical in function to &rest, but it can be used to inform
certain output-formatting and editing functions that the remainder of the
form is treated as a body, and should be indented accordingly.
#+end_quote
--- [[http://clhs.lisp.se/Body/03_dd.htm][CLHS, 3.4.4 Macro Lambda Lists]]

cl-macs does support ~&body~; however toplevel ~&body~ does not affect
indentation.  This can be fixed by augmenting the definition of
~cl--transform-lambda~ as follows:
#+begin_example emacs-lisp
(when-let ((according-to-&body
            (let ((counter 0))
              (cl-dolist (x orig-args)
                (cond
                 ((eq '&body x) (cl-return counter))
                 ((not (memq x cl--lambda-list-keywords))
                  (cl-incf counter)))))))
  ;; Placing the declaration in the end
  ;; allows overriding the indentation setting
  ;; with an explicit (declare (indent ..)) statement
  ;; manually written in the form being expanded.
  (setq header
        (nconc header
               (list
                `(declare (indent ,according-to-&body))))))
#+end_example

See the attached patch for details.  I hesitate to recommend using the
patch as is because my use of ~cl-dolist~ likely interrupts the flow of
cl-macs.  In fact, the patch as is might actually break the build:
unfortunately, I cannot do a test build of Emacs right now.  I thus did
not try to polish something I wouldn't actually be able to test.  The
patch is provided for the sake of completeness.

Now to (possibly incomplete) summary of the 2005-07 thread and
comparison.

The feature was
- suggested to be applied to usual ~defmacro~ as well
- not implemented as there is no ~&body~ in ~defmacro~
- apparently shelved and then forgotten about

I only suggest to alter ~cl-defmacro~.

In addition, 2005-07 solution
- is implemented with ~(put .. 'lisp-indent-function ..)~
- does not check for preceding keywords

The link:
https://lists.gnu.org/archive/html/emacs-devel/2005-07/msg00457.html

I check for all ~cl--lambda-list-keywords~.  This is excessive but it
also makes for a cleaner code, properly treats arglists with
~&optional~, ~&whole~ (if ever implmeneted) and whatever else happens to
be in the arglist; note that according to Common Lisp specification,
arglsits can actually have arbitrary keywords.  ~&whole~ is only
relevant for macro definitions; arguably, it does make sense for
~cl--transform-lambda~ to take these types into account but I believe
the presented approach is good enough, and using &-keywords as regular
arguments in, say, ~cl-defun~ is certainly not a good idea.

As to whether the macro better inject ~(put ..)~ or ~(declare ..)~ form,
my preference is for the latter because
- I find it preferable to modify headers rather than the body
- I strongly prefer to generate code I myself would have written.  This
is apparently not a conventional practice in Lisp; mistakenly, I
believe, but that's offtopic.

Just in case, I have signed the papers already.

reply via email to

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