11

Take the following example macro, defined in macro.el.

(defmacro some-macro (&rest body)
  `(let ((some-variable 1))
     ,@body))

And take the following function, defined in a different file, function.el.

(defun some-function ()
  (some-macro (do-something)))

When function.el is byte-compiled, will some-variable be bound under lexical or dynamic binding?

I understand this depends on whether the file uses -*- lexical-binding: t; -*-, so my question specifically regards the following situations:

  1. If function.el uses lexical binding, but macro.el doesn't.
  2. If macro.el uses lexical binding, but function.el doesn't.

Does it make a difference if some-var has been declared global (with a defvar) inside function.el? If it does, I'm specifically interested in the case where it hasn't.

  • I think Jisang Yoo covered this in some detail at yoo2080.wordpress.com/2013/08/14/… – phils Dec 15 '14 at 21:34
  • I don't know for sure, but I'd bet that the macro expansion inherits the binding semantics from the expansion site, not from the macro definition. That'd make sense since the expansion is actually substituted at the call site. But: Why do you want to know? Do you intend to write code that actually relies on these details?! – lunaryorn Dec 15 '14 at 21:55
  • @lunaryorn the macro doesn't completely rely on this, but it might produce surprising bugs to the user if it doesn't respect the binding of the file it's used in. – Malabarba Dec 15 '14 at 22:01
  • @Malabarba Write your macro in a way that does not rely on the binding in the target buffer, then. Or even better, don't use a macro at all. – lunaryorn Dec 15 '14 at 22:07
  • @lunaryorn I wasn't quite clear. The macro is just a let form, and it works as advertised either way. I just want to make sure this let form follows the scoping specified in the file it's expanded in. This question is part of finding out whether that happens automatically or if I need to code that in the macro. – Malabarba Dec 15 '14 at 22:24
9

The kind of scoping active for the (let ((some-variable ..)) ...) in your example, is the one active at the site of the macro call (i.e. the one that applies to some-function).

A macro can know which kind of scoping will be used for the code it returns by checking the value of the lexical-binding variable.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.