[Top][All Lists]

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

Re: A combination of defmacro, functionp, and quoted lambdas yields diff

From: Stefan Monnier
Subject: Re: A combination of defmacro, functionp, and quoted lambdas yields different results on consecutive evaluations
Date: Wed, 28 Feb 2018 11:02:33 -0500
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux)

> One of the issues to consider is that the usual fix of (require)-ing —
> or (require-when-compile)-ing — the package that defines the macro
> isn't satisfactory in this case, since with-eval-after-load is used to
> run code *after* the package is loaded.  And, since eval-when-compile
> now behaves the same way, there doesn't seem to be a user-friendly way
> at the moment to delay the execution a bit of code that includes
> macros until these macros are available.

We could add a new macro, which does kind of the "reverse" of

    (defmacro dont-compile-before-eval (&rest body)
      "Wrap BODY to hide it from macroexpander and compiler.
    BODY will not be compiled nor macroexpanded until the code is
    actually evaluated.
    Note: BODY cannot refer to surrounding lexically scoped variables."
      `(eval '(progn . ,body) ',lexical-binding))

to make it slightly more "user-friendly".

I have several times been tempted to tweak the byte-compiler and
macroexpander to automatically do this kind of wrapping when faced with
a call of the form (FOO ...) where FOO is not known at all
(i.e. instead of presuming that FOO will be a function), but the "Note:"
above would make such an auto-rewrite only safe when there's no
surrounding lexically-scoped vars (i.e. at top-level or when
lexical-binding is nil).

> Btw, autoloading these macros wouldn't fix this, right?

Yes and no: it would make it behave semantically correctly, but it would
cause flycheck to be loaded eagerly, just as with "require-when-compile".

> I think we've had that particular issue for a while in Flycheck — it's just
> that we didn't understand it until fairly recently.  It pops up when people
> put stuff in their use-package configuration, in particular.

Similar problems show up when package FOO wants to provide support for
interacting with package BAR but doesn't want to force BAR to be
a dependency: if the support for BAR involves the use of macros provided
by BAR, then you need extra gymnastics to prevent the byte-compiler from
mis-compiling the files when BAR is not (yet) installed.

Another related situation is when package FOO wants to use a feature
(and associated macro) only available in Emacs>NN.MM. Using the usual

    (when (fboundp 'blabla)
      (blabla ...))

is sufficient except when the file is compiled with Emacs<NN.MM and then
used on Emacs>NN.MM since the (blabla ...) was miscompiled.
AUCTeX uses a macro `TeX--if-macro-fboundp` to encapsulate its
solution to the problem.

The cleanest solution is to avoid macros ;-)

        Stefan "who loves macros"

reply via email to

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