emacs-devel
[Top][All Lists]
Advanced

[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: Mon, 26 Feb 2018 12:31:45 -0500
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux)

> Is that actually a usable criterion?  Any macro can quote or unquote its
> argument, right?

Everything can happen, indeed.  But usually a macro which takes a code
argument and puts it within a quote is perceived as a problem: e.g. it
tends to very quickly annoy its users because they can't refer to
lexically-scoped arguments any more.  Admittedly, for
with-eval-after-load this is not very problematic because it's unusual
to have with-eval-after-load elsewhere than at top-level, so making code
like:

    (let ((x 1))
      (with-eval-after-load FOO
        (message "%S" x)))

work correctly is not nearly as important as it is for many other macros.

Code looks a lot like data, but for reasons of lexical scoping,
*variables* are quite different from symbols, yet we don't have any data
to represent *variables* (so we use symbols instead).

> For example, the problem that I described about with-eval-after-load
> also happens with eval-after-load, yet the argument to that is quoted.

[ I was wondering when someone would notice.  ]

Indeed, when I introduced `with-eval-after-load` and I also changed
`eval-after-load` by adding a compiler macro which turns

     (eval-after-load FOO 'BAR)
into
     (eval-after-load FOO `(,(lambda () BAR)))

so that BAR can be properly eagerly macro-expanded, so the
byte-compiler can look at BAR and emit warnings about it, and also so
that BAR will be interpreted using lexical-binding if the containing
file uses lexical-binding.

Here's the kind of thing I had in mind (can't think of any concrete
example for it, tho, the motivation came from such cases in defadvice
and interactive forms instead, which had the same problem is keeping
code quoted thus preventing compilation and eager macroexpansion):

    (eval-when-compile (require 'cl))
    (eval-after-load FOO '(flet ...))

There are a few other places where we "undo" a quote, as in

    (mapcar '(lambda ...) ...)

These were all done because it seemed to be beneficial more often than
it is harmful.  I must admit that I wasn't 100% sure that "unquoting"
its arg was "more often beneficial", tho the fact that I haven't heard
anyone even mention this until now seems to argue that even tho it's
maybe not "more often beneficial" at least not often harmful.


        Stefan



reply via email to

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