Fork me on GitHub

Does anyone have info on the significance of :topo vs :bfs sort orders in b/compile-clj?

Alex Miller (Clojure team)15:05:33

they take the set of namespaces in your project and order them for compilation

Alex Miller (Clojure team)15:05:06

:topo will create a graph of namespace dependencies, topologically sort them, and then compile in reverse order (so least depended on to first)

Alex Miller (Clojure team)15:05:37

:bfs is basically breadth-first-search on namespace name


And why would one choose either of those? (perhaps clearer if worded "choose one over the other")

Alex Miller (Clojure team)15:05:29

certain orderings will cause problems with protocols, in particular compiling a namespace that extends a protocol first it will walk the require and compile the namespace that defines the protocol, then the implementation, then later it will encounter the definition namespace again, which will make the prior definition class stale

Alex Miller (Clojure team)15:05:04

so you almost always want to compile in :topo order, which is the default

Alex Miller (Clojure team)15:05:20

the other one existed first, and so I kept it with an option


Oh, very nice, thank you for the explanation!

Alex Miller (Clojure team)15:05:58

and left room for some future option that I have not yet conceived of

Alex Miller (Clojure team)15:05:31

you can also of course explicitly declare a list of namespaces to compile which will do neither of these


@alexmiller Does specifying only a top level namespace have the same effect as specifying a top level namespace + one of its dependencies when compiling with topo, or will it compile the dependency namespace twice? (if so, why would you ever want to compile a namespace twice?)

Alex Miller (Clojure team)19:05:05

it will never compile twice - compilation is a side effect of load, and load keeps tracks of what namespaces have been loaded (and thus compiled)

Alex Miller (Clojure team)19:05:44

I'm not sure if that answers your question


it will compile twice because compile-clj calls compile directly which doesn't check the var where load libs are stored

Alex Miller (Clojure team)20:05:44

oh, that's true. but the second time, I think load will just load the already compiled class, which is newer than the source