My last post covered the rationale behind our team at an investment bank wanting to make a switch to Clojure from Java. I want to write in this post about how we were supported in our efforts by those at the bank.
Aircover from Within
First not all the team jumped in at once to use Clojure. We created what we called a ‘pod’ within our team. Invitation to the pod was extended to all but to join you had to get the Emacs/Swank/Lein environment setup working first by reading our projects github README page. People joined the pod at varying times with their own personal approach. I.e. some devs wanted some space to try out their own thing in the Clojure codebase whilst others wanted to pair up. Some devs wanted to install the very latest version of Emacs themselves and understand all of our Emacs config whilst others took a more direct route through to the code. At one point we had an Emacs versioning arms race of which I dropped out.
Some of the team didn’t join the pod initially and stayed back to provide air-cover to those within the pod. For the system we had to maintain/develop they stepped up to satisfy whatever business requirements came our way as well as handling any emergent technical problems. Gratitude is owed and deserved.
Technical Leadership Vs Bottom Up, Organic Adoption
I’ve heard of a case at a different investment bank of someone fairly senior decreeing that development going forward needs to be done using Clojure (I disclose now that I don’t have all the facts). I’m not sure how I feel about the idea of this. On the one had it feels good that someone high up has got a kick-ass mentality to drag up the quality of the tools that people in the trenches are using to eliminate waste and to speed up development. On the other hand I can see some people getting frustrated – i.e. not everyone wants to get bloody on the cutting edge and to call themselves Lisp hackers, having to revert from the cosy wizardry of professional refactoring powerhouse tools like Eclipse/Intellji to having to use Emacs or Vim, tools of old.
Changing from a statically typed OO language to a dynamically typed FP one is a fundamental change requiring lots of organic support and I’d be interested to hear if it can be forced or not. Maybe it can be. Maybe this is good. There’s also still immaturity around the Clojure tools ecosystem to grapple with. Nrepl is replacing Swank-Clojure, Lein 2 is about to be released which is a major upgrade. Although you can get copious amounts done using Clojure one has to say that the ground still has the occasional tremor and this may affect bringing onboard the masses. I would expect that there is lots of devil in the detail around Clojure mass adoption.
At our bank we were given some room and trust to take technical decisions so long as our cost/benefit case was solid. It felt right for our team at the time to start using Clojure – we were not instructed to do so.
Support from the Business
The Business were typically not as patiently supportive as our technical stakeholders. However pleasant our business customers are there’s always an element of ‘why we have got X amount of the team diverted away from serving the direct requirements of the business to do tech stuff?’
It may sound obvious but the only effective way I’ve found to deal with this is get a synergy between the ‘tech stuff’ and needs of the business as soon as is reasonable. Our pod of Clojure devs made a switch from straightforward 100% reengineering to doing a mixed blend of new requirements for the business too. Now the business are happier and we get some relief. Since development is more productive around our new infrastructure we can turn around long standing requirements for them faster and it’s fun to do. They will reap the rewards from here on in.
This does however mean that we’ve increased the amount of work we’ve signed up for and overall pressure on ourselves, this has affected our morale. We are currently sailing quite close to the wind with anti-patterns ‘scope creep’ and even at times ‘death march’ hovering. There’s no doubt that we’ve had our share of stresses and that there are more to come. I can though take some comfort that with hindsight the thought of sticking with the old status quo of a monolithic Java app does not become any more appealing. Eventually the waste will crush no matter what the resources of an institution.
An increasing number of large institutions are now wanting to leverage Clojure. Large institutions are inherently complex and can often be dysfunctional in various areas. They do however attract lots of very good people and good people often bring with them the best tools.
Investment banks in particular have hard problems to solve. The financial instruments themselves have varying degrees of complexity, although whatever complexity they have often pales in comparison against the systems ecosystem that maintains them. I said once to a senior manager at one place that the number of systems I was seeing in various strates reminded me of Darwin’s survival of the fittest, beasts coming in all shapes and sizes. He said I was wrong because in the wild animals actually die rather than live on to relentlessly cause problems.
Over a year and half ago I was a team lead on a medium sized development team running a strategically important middle-office system. We were 100% a Java team and we had some pretty good devs onboard with decent backgrounds. We had plans to split up our Spring/Hibernate 1 million LOC behemoth and were getting in some decent wins to make this happen. Then I persuaded a Swedish colleague I’d worked with before to come work with us. I had the feeling the team needed someone to come in to and give us a kick and to challenge our general direction – he certainly lived up to this. Large scale refactorings I was fairly proud of he denounced as ‘just moving shit around’. If we were serious about changing our system then the only way to do this was to change our course radically. Although he was challenged fairly robustly – to the extent that at times I know he got quite pissed off – a few things we were already conscious of.
Firstly Java encourages lots of modelling. “Let’s sit down with all the power of OO and create of lots of classes that attempt to model the problem at hand. We won’t use UML but instead we’ll evolve it in an agile way.” The model in the investment banking world is actually quite complicated so this OO graph grows quite large. Abstraction is brought in do deal with variance; abstract classes and interfaces proliferate. The type system encourages this. I had used some dynamical languages before and it was quite obvious that we were essentially forcing lots of schema and type definition on to a problem domain that just didn’t want or need it. Sure you can minimize the pain with patterns such as composition over inheritance, better abstractions etc, but we had already admitted to ourselves in some quarters that we were fighting the wrong battle.
And soon it becomes like wading in cement. Our system was predominately conceived around 2007 when it was the heyday of using Test Driven Development (TDD) and to have a heavy reliance on dependency-injection frameworks like Spring. I should state now that I don’t actually dislike Spring with any religious fervour – it just looks redundant in retrospect now that I’m working 95% with FP code. Our app back then also had lots of Mock framework usage – we had both JMock and Mockito flavours. Before our big move to Clojure I’d already decided I just didn’t get on with mock frameworks. They slow down development as you constantly find yourself fighting against lots of incomprehensible tests written dogmatically that rarely test anything useful. I really can’t really think of many situations right now when using Mocking would be a good idea, even in a Java/OO setting.
I had also picked up a consensus view amongst industry peers that the only way to truly break up a big monolithic system like ours was to enforce hardline decoupling around service boundaries. The best way to achieve this is naturally to use different languages. If we’d have stuck with Java we’d never have ‘gone for broke’ to drop a crowbar into our system and to wrestle it apart. Now we’re using Clojure this is essentially what we’re doing, and not in a bad way.
You also need to ask yourself when contemplating a fairly seismic shift of tool usage what about the business? What about the stakeholders? Who is going to pay for this kind of re-engineering and why?
In the end there are a lot of answers to these questions. My answer of choice tends to be waste. Waste on the scale lots of project have should not be tolerated. Waste in terms of time spent wading through cement-styled Java, time spent hunting through layers upon layers of indirection, interfaces, unit/integration/acceptance tests, Spring XML files, just to find the one if-statement that actually has some business significance, Eureka! We had/have waste on a fairly large scale and to start developing our system in a fundamentally different way almost seems the only sensible option especially if you want people to stick around.
Here are some specifics – our new code is going to be an order of magnitude less in volume than the old and this is being conservative. With the new code you can use your REPL to navigate in and to run any little bit of it you like. You can change any code and see the changes immediately in your browser (our app lives inside of web-server instances) or REPL. Instead of modelling the world, every man and his dog, we’re going to instead write code that operates against simple data structures. If then we need to be able to determine what is actually going on – wtf – we’ll add lots of introspective abilities to our code. In short, to replace copious amounts of Java code along with built up DSLs that only devs use, we’re going to build a simple rule engine. And we’re going to provide some visualisation tools so that you can actually see the rules themselves. A rule editor may follow.
Sure we had lots of debates about why we couldn’t do what we need to do in Java, and in the end it became clear that you couldn’t really have the debate on these terms. The decision of switching to Clojure fell in to three natural brackets. 1) What’s good for the long term nature of the project? 2) What’s good for this present team? and 3) What’s good for the individuals involved? 1) FP seemed a better fit for our system – it’s basically functional blocks of code hanging of financial market events. Our system also suits a dynamic language making all the rigid schema definition less of a problem. On a different tack surely the long term view project is best served by using the best tools and being able to attract the best people. 2) The team will be motivated learning something new and we’ll likely get better retention. This is ultimately good for the costs of the business. 3) The majority of the team wanted to try Clojure. As Hakan made the point – we don’t get paid to enjoy ourselves at work, but it doesn’t hurt. It’s an obvious point – a happier team is more productive.
In the end at some point a team just has to take a jump. Certainly there’s been problems and long standing issues in our move to Clojure and there are some significant questions still yet to be resolved. We’re a global team and this brings with it a wealth of complexities. A year ago we were also a bunch of Clojure newbies finding our way and some of our code and decisions reflect this. I’ll write about these in a subsequent post.
We’re roughly coming up to a year anniversary of when myself and a ragtag bunch of pan European devs started to use Clojure for our day jobs at an investment bank working on on a strategically important middle-office platform. Hakan Raberg is the change agent that when joining the team argued the case for moving to Clojure to whom I am indebted. Hakan and I did a talk at EuroClojure talking about the project – video here.
We’re also going to talk this week at FP Day in Cambridge. Here we’re going to address ‘Clojure after the honeymoon’. Here we want to give an honest account of the problems we faced introducing Clojure inside somewhat of a conversative environment, and of what is the current state of Clojure is. We also want to talk about some of the technical challenges we had particularly around making the jump from Java to Clojure. Hakan left the project to rewrite Emacs in Clojure and to widen his brain neural pathways even further, I’m still on this very project dealing with the fallout.
Time permitting I hope to write up some of our experiences talking about some of the cultural shifts and also about some of the technical stuff we did – i.e. our approach to regression testing, our Clojure rule engine, and the continued battle inside and out of a large Java monolithic beast. I’ll do this in a short series of posts.