Open question on dependency injection in Clojure
I was musing today about some things I’ve seen in Clojure and their relationship to dependency injection in Java, etc. I wanted to draw the connection and then see what people in the Clojure community thought about it.
I’ve used dependency injection in Java for a long, long time both with and without DI frameworks. I use them to make dependencies explicit and to manage how and from where code gets those dependencies, which subsequently makes code easier to reuse and easier to test.
For example, if I’ve got some class that needs a source of timestamps, I might create a TimeSource interface and an implementation of TimeSource that uses System.currentTimeMillis() and pass it to the class in the constructor instead of just calling System.currentTimeMillis() directly in the class. In the past, I’ve used such techniques to unit test annoying time-dependent code (for example code that has timeouts) by mocking the TimeSource so that I can “control time”. JSR 310, the forthcoming Date and Time API, has this concept as well.
In general, as I’ve written Clojure code I have no need for DI or at least in any way recognizable from a Java background. But I did recently see an analog to how DI is used above in Clojure. It’s not uncommon though to see a Clojure variable defined as *time-source* and a set of functions that make use of the time-source. And you then might choose the time-source impl to use with a macro that binds *time-source* to a particular instance with something like (with-time-source) or requires a set! on the thread-local binding for those variables.
It seems like the code in those functions is relying on an external resource which is being injected into a well-known variable instead of through the function signature. That feels a little to me like a Java class that depends on a resource obtained through some well-known lookup mechanism (whether that might be a static factory method or a service locator, etc) instead of by using dependency injection.
I’m a little conflicted about whether this seems good or bad. It seems like it’s the same kind of code that I would rewrite with dependency injection in Java for all the usual reasons. But in Clojure you aren’t calling static state and you are still perfectly capable of changing the implementation used for that resource at will, so those downsides of static calls in Java don’t seem to apply.
Am I capturing this Clojure idiom properly? Is this case analogous to what I describe in Java or is not? Why are the issues in Java not issues in Clojure?

Hi! My name is Alex Miller and I live in St. Louis. I write code for a living and currently work for
It seems that vars in clojure are essentially orthogonal to DI in Java. Keeping in mind that I’ve avoided DI (and most “modern” java-isms) like the plague ‘lo these many years, I’d say that talking about them with the same breath is odd to me to begin with. You can certainly implement DI using vars, but that’s the least of it.
The most common usage of vars (aside from holding top level functions and such) is to define some bit of configuration associated with a specific namespace. You can see this in the case of clojure.contrib.sql’s with-connection macro and the associated vars.
Then there’s managing state orthogonal to the stack. See the usage of *response-code* below, where an http response code is swap!ped into a bound atom, and can be picked up N stack frames above the caller, either in response to a thrown error or not (there’s a specific term for this practice, using bound vars to pass “out-of-band” return values outside of the stack):
http://github.com/tashafa/clutch/blob/1.1-compatible/src/main/clojure/com/ashafa/clutch/http_client.clj
Then there’s outrageously ambitious stuff like chouser’s error-kit, which depends upon vars to completely subvert calling conventions to suit one’s preferences:
http://github.com/richhickey/clojure-contrib/blob/master/src/main/clojure/clojure/contrib/error_kit.clj
And, there’s various test frameworks about that use vars to stub out apis stupidly easy. (Not worth it in clojure IMO, but anyway…)
As for what you describe in Java — injecting a TimeSource interface, etc — that wouldn’t be done with a var in clojure, that’d be done by closing over a function: #(System/currentTimeMillis). Done. :-) More complicated usages don’t require much more.
Alex,
You can also use the binding form to provide alternate values for vars during testing. If time-source were a function, and the function that you are testing calls time-source, then you can use binding to replace time-source within the scope of your test.
I have found that while testing, binding eliminates a lot of what I would use DI for in Java.
Brenton
I’m with Chas for the most part. Dependency Injection is a poor-man’s closure. I’ve been thinking recently that using global Vars for configuration is a bad idea in a multi-threaded environment; closures with explicitly-passed parameters are more robust and flexible.
The difficulty, I think, is that dependency injection is not usually just about injecting or overriding single dependencies, it’s about binding graphs of values. In the simple case DI lookup seems like a map, where “dataSource” points to the implementation of the DataSource class. But in apps where I see, e.g. Spring being used, the DataSource implementation can itself get a connection pool injected, the pool gets a JDBC driver injected as well as individual properties for pool size, etc. The magic of DI is that if you visualize your (OO) app as a set of object graphs, you can, at runtime, replace either individual nodes or whole sub-graphs dynamically. That’s really what makes it so powerful. In Java this is more or less managable because class fields and class types offer a natural way to organize the mapping of the overrides. So for me the question would be how to override any of a set of functions used within a Clojure app no matter how deep those functions are defined, without making a mess of it.
I am just learn Clojure and trying to wrap my brain around it. But this is a great blog post as I too see graphs of objects being injected into Java apps. Sometimes I wonder if the Clojure community actually knows modern Java development and practices, or left years ago and I are unaware of how DI is part and parcel of most JEE development now as is testing. And with testing comes mocking. So yes, I am a newbie, and yes perhaps the light will ‘turn on’ when I get it. But I also fear no one is writing real EE like apps in Clojure and it’s all just another brainy academic exercise. How do you mock out things (lot of things) in Clojure? Guess (I hope) I learn…
I have been working exclusively in Java for past 10 years and love DI when I am using Java. I understand where these questions come from because I struggled with them at first. You are trying to figure out how to write Java programs in Clojure. The fact is, you don’t. In Clojure, you don’t create object graphs and therefore you don’t have to figure out how to mock everything. A large Clojure program will have data and functions and a small amount of explicit state management. There are very few situations where you need to do anything like mocking in Java and for that you can use Clojure’s binding form.
Hi Alex,
I also agree with Chas, but I’d like to add one thing. I have felt for years that dependency injection and aspects were a poor man’s substitute for functional programming. Aspects are a little more powerful but I feel that if you have a language, libraries and framework that are built so they expect behavior to be passed around then you no longer need dependency injection or aspects. In fact, a lot of the patterns that we are used to in the OO space seem to be irrelevant when working in the functional paradigm.
Regards,
Daniel