This works:
(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 byclojure-mode, which is not loaded by default. Sodefine-clojure-indentis only defined after(require 'clojure-mode)is evaluated.- Since both the
requireand thedefine-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. - Both
->and->>are macros defined bydash.el, which I also had loaded. They have the behavior that both of the forms(-> 1)and(->> 1)expand to just1. It appears that since Emacs does its macroexpansion on the
define-clojure-indentform before it has loadedclojure-mode, it does not yet know thatdefine-clojure-indentis actually a macro. Therefore, it goes ahead and macroexpands recursively, transforming(define-clojure-indent (-> 1) (->> 1))to
(define-clojure-indent 1 1)by interpreting
->and->>as macros instead of simply unevaluated symbols.When
clojure-modeis actually loaded anddefine-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 require and 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.)