From: Ergus <spacibba@aol.com>
To: Stefan Monnier <monnier@iro.umontreal.ca>
Cc: help-gnu-emacs@gnu.org
Subject: Re: Simple macro question
Date: Mon, 3 May 2021 13:32:56 +0200 [thread overview]
Message-ID: <20210503113256.hjuw7jyhtpnxqnku@Ergus> (raw)
In-Reply-To: <jwv35v4y4re.fsf-monnier+emacs@gnu.org>
Hi Stefan:
Thanks for the reply.
IIUC then this code:
====================
;;; test.el --- test editing -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(defun test-fun (com)
"Testfun with COM."
nil)
(defmacro test-def (thelist)
"Doc def."
`(progn ,@(mapcar #'test-fun thelist)))
(test-def (A B C))
(provide 'test)
;;; test ends here
============================
Will require to put the test-fun inside an `eval-and-compile` too?
Because I am getting a similar error, this time test-fun is not defined.
I tried to use eval-and-compile in this case but the problem is that in
my real code test-fun calls another function (a minor mode) that needs
to be defined later (in the same file); and I get an error in that case
too that the minor-mode-function is not defined.
What's the canonical way to do that? use declare function? some trick
with the quoting? Put also the minor mode inside an eval-and-compile?
In case you are interested into why I came into this issues, here is the
code:
https://github.com/Ergus/composable.el/blob/master/composable.el
In the future I want to implement another version using the new
`repeat-mode` api, that will be cleaner, but at the moment it does not
makes sense as there is not any emacs release with the repeat api yet.
Thanks in advance,
Ergus
On Sun, May 02, 2021 at 09:46:30PM -0400, Stefan Monnier wrote:
>> (defvar test-commands-list '(A B C)
>> "List of replaced functions.")
>> (defmacro test-def ()
>> "Doc def."
>> `(eval-and-compile ,@(mapcar (lambda (com) nil) test-commands-list)))
>> (test-def)
>
>[...]
>
>> Symbol’s value as variable is void: test-commands-list
>
>macro-expansion takes place during compilation. During compilation, the
>code is mostly translated, not evaluated, but macros are expanded.
>So your `(test-def)` macro call is expanded which evaluates the code
>inside `test-def` whereas the `(defvar ...)` code is not evaluated (it's
>only translated into byte-code) and hence the var is not defined: it
>will only be defined much later when the resulting byte-code is run.
>
>One way to work around it is to place the `defvar` within an
>`eval-and-compile`.
>
>> (defmacro test-def (commands-list)
>> ...
>>
>> (test-def test-commands-list)
>>
>> In this second case I get: wrong arguments sequencep test-commands-list
>> Is this intended?
>
>Yes: the argument to macros are the actual sexp written in the macro
>call, not the result of their evaluation. So your argument
>`commands-list` will hold the symbol `test-commands-list` rather than
>the list you were hoping to get. You could use `symbol-value` to get
>the content of that symbol as a variable, but then you'd be back to the
>previous problem because the `defvar` has not been evaluated yet.
>
>
> Stefan
>
>
next prev parent reply other threads:[~2021-05-03 11:32 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20210503000712.l2wh2liwhg3jfjxy.ref@Ergus>
2021-05-03 0:07 ` Simple macro question Ergus
2021-05-03 1:29 ` Ergus
2021-05-03 1:46 ` Stefan Monnier
2021-05-03 11:32 ` Ergus [this message]
2021-05-04 19:54 ` Stefan Monnier via Users list for the GNU Emacs text editor
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
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210503113256.hjuw7jyhtpnxqnku@Ergus \
--to=spacibba@aol.com \
--cc=help-gnu-emacs@gnu.org \
--cc=monnier@iro.umontreal.ca \
/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.
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).