(require 'clojure-mode) (when (member 'clojure-mode my-packages) (define-clojure-indent (-> 1) (->> 1)))
This gives the error
Wrong type argument: listp, 1:
(when (member 'clojure-mode my-packages) (require 'clojure-mode) (define-clojure-indent (-> 1) (->> 1)))
Here's what I think is happening in the second version:
define-clojure-indentis a macro defined by
clojure-mode, which is not loaded by default. So
define-clojure-indentis only defined after
(require 'clojure-mode)is evaluated.
- Since both the
define-clojure-indentcall are in the same top-level form, all macroexpansion happens before any evaluation happens. This appears to be similar to the Gilardi scenario from Clojure.
->>are macros defined by
dash.el, which I also had loaded. They have the behavior that both of the forms
(->> 1)expand to just
It appears that since Emacs does its macroexpansion on the
define-clojure-indentform before it has loaded
clojure-mode, it does not yet know that
define-clojure-indentis actually a macro. Therefore, it goes ahead and macroexpands recursively, transforming
(define-clojure-indent (-> 1) (->> 1))
(define-clojure-indent 1 1)
->>as macros instead of simply unevaluated symbols.
clojure-modeis actually loaded and
define-clojure-indentis invoked as a macro, it throws an error because it expects its arguments to be lists, not integers.
Whereas in the first version, since the
define-clojure-indent are in different top-level forms, by the time Emacs gets to macroexpanding the
define-clojure-indent form, it already knows that
define-clojure-indent is a macro, and doesn't try to do macroexpansion on its arguments. So
(-> 1) and
(->> 1) are passed to
define-clojure-indent as lists of symbols, as I would expect, and everything works.
So here is my question. If Emacs doesn't know whether or not something is a macro, why would it do macroexpansion on the arguments? In this situation, it clearly produces unintended behavior. As far as I know, this would never happen in the Clojure macro system. And I can't think of any situation in which the current functionality would be desired.
Surely I am missing something here. Is there an elegant way to avoid this problem? Or do I have a fundamental misunderstanding?
(P.S. I am aware that I could use
eval-after-load. The same problem still occurs, but I used
require in the example because it was simpler. Full code—obviously not yet working, because of this and other errors—available here.)