Someone recently posted this to the clojure mailing list:
I found passing around the database connection to each function that uses it very error prone when you are using transactions as passing the wrong one could mean a query runs outside the transaction when in the source code it is inside the with-db-transaction function.
The general consensus boiled down to “Don’t do that. Go back to passing the database connection through your request handler chain as a function parameter instead.”
I’ll go ahead and make the point that it’s error-prone for different reasons.
Pretty much by definition, that database connection is a system boundary. It’s all about something that’s *way* more complex than random global state changes inside your program. This is a thing that interacts with the outside world, with all the nastiness that implies.
Everything that everyone else has already written about this approach is true, but I don’t think they’ve gone far enough.
Even if you pass that database connection around as a parameter everywhere, you’re talking about throwing away a huge part of the benefit of using a functional language.
Isolate your side-effects.
Think of a castle. You have a moat surrounding it, and a few gates that you use to allow your peasants to enter/exit. This particular gate opens up to a swamp full of alligators.
Your approach amounts to letting the gators wander around loose.
Passing the connection around to each function in the call chain is like tying a ribbon around the gator’s neck and hoping you can use that as a leash.
You can use either approach to great effect. If you’re really, really good. And so is everyone else on your team (you did mention a 200 KLOC project).
One of the main benefits to functional programming is that admitting you aren’t really, really good is incredibly liberating. I don’t have the time/energy to dedicate to trying to maintain this sort of code. (Yes, I spent lots of time recently thinking about how java was designed for very average programmers, but it really takes much better programmers than a functional language to actually write correct programs). Even if I were that good…I’d rather be focused on the problems that make my customers happy.
I’m going to appeal to authority here for the right answer: http://prog21.dadgum.com/23.html (in my defense, it’s a great blog). Have your web response handler (which is another system boundary…this one is next to an active volcano populated by fire-breathing dragons) build up a list of all the nasty side-effects that will eventually have to happen.
Don’t just isolate your side-effects. Quarantine those suckers as if each and every one means you’re dealing with the most diabolical hacker you can imagine.