17

TL;DR: when is about side effects, and is for pure boolean expressions. As you've noticed, and and when differ only in syntax, but are otherwise entirely equivalent. The syntactic difference is quite important, though: when wraps an implicit progn around all but the first argument forms. progn is an inherently imperative feature: It evaluates all but ...


15

The defcustom expression are not evaluated during byte-compilation, so when your macro is expanded, the variable does not exist yet because that defcustom was compiled but not run. You can either move the defcustom to another file (which you then require at the beginning of your file), or you can wrap the defcustom inside eval-and-compile.


14

Rule of thumb Use macros for syntax, but never for semantics. It's fine to use a macro for some syntactic sugar, but it's a bad idea to put logic into a macro body regardless of whether it's in the macro itself or in the expansion. If you feel the need to do that, write a function instead, and a "companion macro" for the syntactic sugar. Simply speaking, ...


13

Here's an attempt at explaining and some suggestion. (defmacro my/create-defun (defun-name) `(defun ,defun-name () (interactive) (let ((fn-name (symbol-name ',defun-name))) (message "Testing creation of function %s" fn-name)))) (dolist (name my/defun-list) ;; Macros are meant to create code, not execute it. Think ;; about simply ...


13

All macros reachable by the byte-compiler are expanded during compilation. "Reachable" essentially means not being quoted. The body of defuns, defmacros, lambdas, are all byte-compiled when the source file that contains them is byte-compiled. So yes, any macro inside them will be expanded, as long as they're not inside a quote ('). A very common mistake is ...


11

You can always unbind the macro when the file ends. As far as I know, Emacs Lisp doesn't have to worry about asynchronous complexities; the flow of execution is purely linear. Therefore, you can do this: (defmacro my-test-macro (secret sauce recipe) ;; super secret stuff here ;; wouldn't want it to LEAK out ;; and get stolen by some other files )...


10

Indeed, there is no support for resumption. Of course, the body of while-no-input can do regular "checkpoints" so as to know where to start next time. But the original motivation for this functionality was in cases where the computed information is likely useless after the next command. More specifically, it was introduced for icomplete, so that the ...


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.


8

From your comment you've figured this out for yourself, but... In the macro expansion you're seeing the printed representation of two independent symbols with the same name. Most likely both of those symbols are uninterned. A printed representation like this, if passed back to the lisp reader, would not be equivalent to the original, as the lisp reader ...


7

As Malabarba has already explained, macros are expanded during byte compilation. If a file is not compiled, macros are expanded when the file is loaded (eager macro expansion). Don't rely on this, though. It's very bad style. You generally can't expect that code which uses your macro is actually compiled, and you should generally run as little code as ...


7

Macros do not evaluate to a result, they evaluate to an expansion, which is a form that substitutes the macro at the place where it's written, the expansion site. The expansion itself is not evaluated by the compiler. As such, you normally don't try to generate function definitions completely. Rather you'd write a macro to performs whatever expansion you'd ...


7

(require <foo>) is treated specially when it's at top-level (it causes the compiler to require the file also, rather than only do the require at run-time). If the require is not performed at compilation time, then your code can't be compiled properly since the define-clojure-indent macro won't be known during compilation, leading to mis-compilation, ...


6

Based on @politza's comment that (of course!) advice works with macros, I found something that seems to work. (defun use-package-always-ensure (form) (append form '(:ensure t))) (advice-add #'use-package :filter-args #'use-package-always-ensure) Note this example is using the Emacs 24.4 advice functions. I haven't figured out what the equivalent would ...


6

Here's what you're trying to do (defmacro iλ (x &optional y) (if (and (stringp x) y) `(lambda () ,x (interactive) ,y)) `(lambda () (interactive) ,x ,y))) And, if you're taking suggestions, here's what I recommend. It should allow you to use any number of forms. (defmacro iλ (x &rest y) (if (and (stringp x) y) `(lambda () ,...


6

Take a look at Missing Macro Tools. It's available on MELPA. The package provides the following classics: mmt-gensym mmt-make-gensym-list mmt-with-gensyms mmt-with-unique-names mmt-once-only


6

You want to splice the list into the new form: `(cond ,@clauses) See C-hig (elisp) Backquote RET You can also "splice" an evaluated value into the resulting list, using the special marker ,@. The elements of the spliced list become elements at the same level as the other elements of the resulting list. The equivalent code without using ` is often ...


6

From my experience reading, debugging and modifying my and others' Elisp code I'd suggest to avoid macros as much as possible. The obvious thing about macros is that they don't evaluate their arguments. Which means that if you have a complex expression wrapped in a macro, you have no idea if it will be evaluated or not, and in which context, unless you look ...


6

find-function won't find macro-generated function definitions due to limitations of Emacs load-history and the workarounds find-function has to resort to. find-function has to explicitly search for the actual source code location of a function definition because Emacs only tracks the defining library but not the actual location of the definition during ...


6

I'd say stick with defun. If you want to try define-inline, which is new (it doesn't even have a doc string yet!), go ahead. But think about how much you want or need inlining. It is rare to need it, IMO (certainly not for the kinds of thing you show here, but they are no doubt just to get the question across). I would definitely recommend not to use ...


5

The newer version of use-package has the following to enable this behavior for all packages: (setq use-package-always-ensure t) Just in case anyone else had the same question.


5

Autoloading only applies to the function value slot of a symbol. In particular, there is no such thing as autoloading a variable. It is probably bad form for a package to contain variables for user customization whose default value is a nonempty list, precisely because it becomes difficult to customize the variable in that case. Worse, if the default value ...


5

Comma and backquote are transformed by the reader into regular function calls with the following sexp as argument. (read "`(list ,fill-column `(list ,fill-column))") ;; => (\` (list (\, fill-column) (\` (list (\, fill-column))))) You can look-up the backquote macro's help. Comma is actually not a macro, but like a marker for backquote, i.e. it's ...


5

1) Does anyone know how to get the above to work? macroexpand-1 is your friend. Let's se what we get by running it: (macroexpand-1 '(idefun my/test () (message "MEH"))) ;; => (defun my/test nil (interactive) ((message "MEH"))) Do you see the problem with that? There's an extra pair of parentheses around the message call. That's because the &rest ...


5

What should work is to drop the eval-after-load: (use-package solarized-theme :ensure t :config ... ;; solarized-with-color-variables is a macro (solarized-with-color-variables 'light ... (setq some-var `(,green box)))) It says that the value of red, "#blah", is not a valid function. I imagine that it's expanding macros twice, once for ...


5

Firstly, that eval-when-compile method works fine for macros. It is a perfectly good way to use macros (not functions) from another package. The problems you report are two different things. the function python-nav-beginning-of-statement' might not be defined at runtime. This is happening because python-nav-beginning-of-statement is a function, not a ...


5

Looks like a macro could do that: (defmacro mylet (defs fun body) (list 'let (append defs (funcall fun)) body)) ;; example uses (defun the-dyn-gen () '((a 3) (b 3))) (mylet ((x 1) (y 2)) the-dyn-gen (+ a b x y)) (mylet ((x 1)) the-dyn-gen (+ a b x)) (mylet nil the-dyn-gen (+ a b)) Disclaimer: while this seems to work, macros can be tricky. Note ...


5

The way you test macros is with macroexpand: (macroexpand-1 '(test-macro "test")) ==> (defun (intern (concat "test-func-called" "test")) nil (message "I do nothing")) This makes the error obvious: the function intern should be called at macroexpansion time, not at evaluation time (since defun does not evaluate its first argument). Thus, the fix is: (...


5

You don't need a macro for this. And you don't need (but you can certainly use) lexical binding. ;; Without lexical binding: ;; (defun advise-once (symbol where function &optional props) (advice-add symbol :after `(lambda (&rest _) (advice-remove ',symbol ',function))) (advice-add symbol where function props)) ;; With lexical binding: ;; (...


4

It's not necessary to use a backquote inside another, that's the beauty of it. (defmacro m1 (a &optional b) (let ((z (gensym))) `(let ((,z (if (integerp ,b) (list ,a ,b) (list ,a)))) ,z))) But that isn't correct yet. The purpose of z isn't to add another variable for the fun of it, but to protect b from ...


4

I don't see an issue. Just macroexpand your stuff and you'll see the obvious errors: (add-annoying-arrows-advice next-line '(ace-jump-mode) evil-next-visual-line '(evil-search-backward)) ;; => (progn (add-to-list (quote annoying-commands) (quote next-line)) (put (quote next-line) (quote aa--alts) (...


Only top voted, non community-wiki answers of a minimum length are eligible