I stumbled across some old code of mine during the last two weeks I was at ADTRAN. We had a really nasty, difficult to reproduce bug and at some point in the code we came across my
ReadOnlyList. Several folks in the room who are familiar with the code immediately expressed frustration with that class. I had written it long before my recent experience in functional programming. This was my first time seeing it since then, and more than ever I felt justified in using it.
As the name suggests,
ReadOnlyList is a
java.util.List that doesn’t implement any of the mutator methods on
List. If you look at the javadocs, you’ll see those methods are all optional. I was certainly not in violation of the contract. I just needed a way to expose a
List without allowing modification.
I’ll briefly give the background on what motivated me to write this class prior to my exposure to programming with persistent data structures. I was working on the project which became one of the defining moments of my career at ADTRAN. We were converting our database from the object-oriented Versant database (version 5.2.2 circa 1998) to MySQL via Hibernate. We had to change out some of the guts of the data access objects to make this work. The old implementation exposed references to the underlying data structures to allow outside mutation and automatically updated the database state with those changes transparently. For whatever reason, we were not able to do that with our Hibernate-aware objects. I needed to explicitly know when a data structure was dirty. Therefore I always returned immutable copies of my collections, expecting the caller to make their own copy, modify, and call the setter.
Unfortunately for the consumers of the objects, this isn’t the easiest thing to do. Likewise, unfortunately for those who desire easy, easy isn’t always simple. And simple trumps easy every time. Perhaps I could have mustered up a way to figure out if a collection was dirty. There may even be a way to let Hibernate do it now (bear in mind this was done several years ago). However, this would have absolutely made the data object class code far more complex. This then makes it far more difficult to reason about. If there is anything my product at ADTRAN needs, it’s simplification so our developers have a chance in Hell to reason about the system. The inability for me to do so in recent versions of the product was a strongly aggravating factor in my decision to resign.
Fast forward to that code review meeting. I’ve been developing in Scala every chance I get for the past several months. I saw this collection I implemented and smiled a little. I’m a huge fan of functional programming with immutable values and persistent data structures. To see that I was realizing the perils of mutability without outside influence boosted my confidence in the philosophy. I ain’t gonna lie; it made me feel like a bit of a genius too.