unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Codifying some aspects of Elisp code style and improving pretty printer
@ 2021-09-29 18:01 akater
  2021-09-30  7:02 ` André A. Gomes
  0 siblings, 1 reply; 11+ messages in thread
From: akater @ 2021-09-29 18:01 UTC (permalink / raw)
  To: emacs-devel

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

Rgrepping lisp/emacs-lisp alone for “(let” and “(if” demonstrates that
there is a reasonable practice at least

- of keeping “then” on the same line as “if” sometimes

- of having several let bindings in “let” on the same line, especially
  if they are all symbols except maybe some first ones.

There is an informal consensus that it's worth it to use whitespace
wisely to keep Lisp forms concise vertically as well as horizontally.  I
think if the idea is recognised as useful it better be explicitly stated
as such rather than remain folklore. I don't see this practice codified
neither in elisp nor eintr Info nodes nor anywhere in Lisp literature
for that matter.  I asked in commonlisp channel on libera.chat and
nobody seems to know of any text like that; pointers are welcome if I
missed something.

True, this is largerly a matter of personal style.  However, there is
also some accumulated experience which I think is worth aggregating.
And no style is actually 100% personal when we collaborate.

I paid some attention to the issue for some time while writing (E)Lisp
code.  There are still some practices I'm not sure about.
E.g. apparently there's no practice to start the first subform of
unwind-protect on the same line as unwind-protect when line width
allows it; I find this surprising as I think this significantly
decreases readablity of unwind-protect forms.

What follows is a draft of relevant style guidelines as I see it.  At
the very least, it can serve as a basis for improving the currently
used pretty printer that prints Elisp forms (which still inexplicably
insists that let forms' bindings should start on a new line, for
example).  Automatic indentation should not attempt to be smart about
line splits but pretty printer should.

I'd welcome relevant bits of github.com/bbatsov/emacs-lisp-style-guide
as well but the guide mentions issues Emacs seems to deal on its own
automatically so I'm not sure.  Also, there may be copyright issues.

When it comes to accessing such information from within Emacs, I could
only find something in (recent) compiler warnings, about long
docstrings, and some other notes about docstrings in CONTRIBUTE file.
Since it has sporadic notes on docstring style, CONTRIBUTE likely
should also reference the style guide as well as Emacs Lisp Coding
Conventions Info node.

So here's the draft.

Emacs Lisp source code layout guidelines

- Rule of thumb: General form should look like

  (f x
     y
     z)

  However, if sequences f x1 ... xn, y1 ... ym, ..., z1 ... zk are
  short as a whole, it is preferred to

  (f x1 ... xn
     y1 ... ym
     ...
     z1 ... zk)

  especially if expressions on the same line are close conceptually,
  e.g. (a) key-value pairs, including those with keyword arguments, or
  (b) pairs of arguments in setq, setf and similar forms.

- “Short as a whole” necessarily means “fits into a single line of
  recommended line width, together with all opening parens” but this
  condition is not sufficient.

- In let, let* and similar forms, a single line can hold as many
  bindings represented by symbols rather than lists, as long as they
  are short as a whole.

- In let* and similar forms, a binding with initial value that depends
  solely on a previous (but not necessarily immediately previous)
  value, can be kept on the same line as its dependency as long as
  they are short as a whole.

- In let, let* and similar forms, if it is posible to arrange
  variables so that conceptually close ones share the same line, it is
  preferred to do so.

- In most (indent n) forms, it is preferred to start (n-1)th
  subexpression on the same line as the head symbol if the
  subexpressions in question are short as a whole and if it allows to
  keep the overall form concise both horizontally and vertically; note
  that it applies to forms ignore-errors and unwind-protect.

- The former applies to cl-loop, cond, let, if forms which do not have
  (indent ..) in their specs but which can nevertheless be considered
  for our purposes as (indent 0), (indent 0), (indent 1), (indent 2)
  forms correspondingly.

- Aside from the very first one, cl-loop keywords should start the lines.

- Two or more forms, short as a whole, that perform what's essentially
  a single step of a loop can be kept on the same line.

- “Short”, “most forms”, “similar forms” in the above paragraphs are
  subjective so the final decision on whether keeping sexps on the
  same line hampers readability or not is up to a maintainer of the
  Elisp codebase in question.  Arguing about such things with
  maintainers is likely a waste of time.  Thus, the maintainer's
  decision on line splits should be considered final.  Refactoring /
  cleanup edits that deal with line splits better be left to
  maintainers, or outsourced by them to someone whose personal style
  they explicitly trust enough to avoid any arguments about this
  matter.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 865 bytes --]

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

end of thread, other threads:[~2021-10-01 17:08 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-29 18:01 Codifying some aspects of Elisp code style and improving pretty printer akater
2021-09-30  7:02 ` André A. Gomes
2021-09-30 11:26   ` Bozhidar Batsov
2021-09-30 15:15     ` akater
2021-10-01  7:05       ` Lars Ingebrigtsen
2021-10-01 14:20         ` Stefan Monnier
2021-10-01 14:43           ` Lars Ingebrigtsen
2021-10-01 14:26         ` Robert Pluim
2021-10-01 15:26           ` Stefan Monnier
2021-10-01 16:15             ` Robert Pluim
2021-10-01 17:08               ` Stefan Monnier

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).