all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Stefan Monnier <monnier@iro.umontreal.ca>
To: Zhu Zihao <all_but_last@163.com>
Cc: emacs-devel@gnu.org
Subject: Re: cl-eval-when -- A workaround for recursive require?
Date: Fri, 29 Apr 2022 13:36:41 -0400	[thread overview]
Message-ID: <jwvee1fremp.fsf-monnier+emacs@gnu.org> (raw)
In-Reply-To: <86v8uuwwho.fsf@163.com> (Zhu Zihao's message of "Wed, 27 Apr 2022 18:52:07 +0800, Wed, 27 Apr 2022 20:16:55 +0800")

Zhu Zihao [2022-04-27 18:52:07] wrote:
> I investigated into the `cl-eval-when` a time long ago about this
> `cl-eval-when` hack in the source of magit here.
> https://github.com/magit/magit/blob/master/lisp/magit.el#L641
>
> A breif summary: magit.el use a `cl-eval-when` block with load time and
> eval time only evaluation to require its sub-components, while each
> sub-component use `(require 'magit)` to use procedure in different
> sub-components. This hack seems to be a hack to avoid recursive require.

This kind of setup is quite common, but the resulting cyclic
dependencies tend to be a nightmare.

> The result of my investigation I remember is: "Don't use cl-eval-when,
> it's not robust for many eval strategy combination. eval-when-compile or
> eval-and-compile are more reasonable alternatives."

I tend to agree.  But when it comes to circular dependencies like that
of `magit.el` the use of `cl-when-eval` is a minor detail.

> The bytecomp.el file is a monolith and I don't know how to read and
> understand it. Curiosity drives me to ask a question here: How does
> `cl-eval-when` hack works for recurisve require? Is it a ugly hack?

There's nothing special about `cl-eval-when` for cyclic dependencies.
Some parts of `cl-eval-when` rely on ugly hacks, but I don't think it
makes much difference here.

The only sane way to solve these problems is to fix the circular
dependencies, really.

Often one of the best tools for that is to rely on autoloads instead of
`require` for some functions, and the better way to do that is to use an
"internal" autoloads file (i.e. one that's separate from the
`<pkg>-autoloads.el` loaded at startup and that's only loaded when the
package is actually used).

See lisp/**/*-loaddefs.el for examples of such "internal"
autoloads files.

We don't have great support for auto-generation of such files, tho, so
sometimes it requires manual work to set it up (if you search for
`;;;###` in `lisp/Makefile.in` you'll see examples of what I'm
referring to).


        Stefan




  reply	other threads:[~2022-04-29 17:36 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-27 10:52 cl-eval-when -- A workaround for recursive require? Zhu Zihao
2022-04-29 17:36 ` Stefan Monnier [this message]
2022-04-30 17:09   ` Zhu Zihao
2022-05-02  0:30     ` Richard Stallman
2022-05-01 18:36   ` Jonas Bernoulli

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=jwvee1fremp.fsf-monnier+emacs@gnu.org \
    --to=monnier@iro.umontreal.ca \
    --cc=all_but_last@163.com \
    --cc=emacs-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.