I found while adding warnings to code that writes macros that the body of a file was being executed twice during compilation. Is there a reason for this? Is this specific to leiningen? I can not reproduce this with (compile ...)
.
Simplified version:
(ns foo.core
(:require foo.bar))
;; empty
(ns foo.bar)
(println "hello")
$ lein compile :all
Compiling foo.core
hello
Compiling foo.bar
hello
Further testing shows that the namespace is reloaded on top of itself during compile:
(ns foo.bar)
(declare wasd)
(println wasd)
(def wasd 2)
$ lein clean
$ lein compile :all
Compiling foo.core
#<Unbound Unbound: #'foo.bar/wasd>
Compiling foo.bar
2
In a more complicated case I have this happening during compile, and then once every time when run or started a repl from lein. I am not sure why. This is all with clojure 1.6 and leiningen 2.5.0.
Leiningen knows nothing about the structure of your project in terms of how namespaces relate to each-other. Consequently, when compiling a project,
lein
simply boots a JVM and forces each namespace to be loaded one at a time. This means that, as you noticed, namespaces will be reloaded causing the double evaluation behaviour you are noticing.In comparison,
(clojure.core/compile)
simply loads the targeted resource withclojure.core/*compile-files*
bound. This will cause the targeted resource and all the resources it requires to be loaded and compiled to class-files. However, it will not traverse your entire project structure compiling all resources as Leiningen's compile operation does.