{
  "$type": "site.standard.document",
  "canonicalUrl": "https://numergent.com/2016-06/Flexibility-Through-Immutability-part-2.html",
  "path": "/2016-06/Flexibility-Through-Immutability-part-2.html",
  "publishedAt": "2016-06-15T07:32:29.000Z",
  "site": "at://did:plc:cf6futaebyc2k4wgzsr4v42k/site.standard.publication/3mp2ewx43js2g",
  "tags": [
    "clojure",
    "immutable data",
    "functional programming",
    "c#",
    "java",
    "re-frame",
    "talks"
  ],
  "textContent": "The second part of the original text for \"Flexibility Through Immutability\".  \n\nThe first part focused on the why of immutable data. On this part I'll review what to do about if you're working on an object-oriented language.\n\n\n\nHow to go about it, the OOP way\n\nThe available tools\n\nLuckily, we already have tools in place that can help you do this, and I'm going to go over four simple principles.\n\nMy focus here will be mostly on how they apply to Cand Java, since .Net and Java is where I've done most of my recent work on, but I'm sure you can take the concepts and translate them elsewhere.\n\nStructs help\n\nStructs can act as a kinda immutable gateway drug. I'm wondering, however... who ends up using more classes than structs?\n\nSo am I suggesting you just struct everything?\n\nNot quite. There's advantages to having classes, like the fact that they're nullable (value types aren't).  But using structs when you can will get you part of the way there, since we do get some enforcement already on what can happen with a struct.\n\nDon't mutate your objects\n\nJust don't mutate your objects. Return a new value instead.\n\nSuppose you have a Vector type. It stores data for a 2D or 3D vector, and has methods to operate on it.\n\nIf you need to normalize the vector (making sure it has the same direction but a length of 1) don't write a Normalize() method that changes it, have a Normalized property that returns a new vector instead.\n\nIf you need to take an Employee record, and increase its salary, don't just to employee.Salary += 100; have a employee.SalaryChange(100) which returns a new Employee.\n\nDoes this sound familiar?\n\nRemember the Builder design pattern? We want to start thinking along those lines.\n\nYou'll also be able to chain operations, and end up with more fluent code.\n\nUse iterators and LINQ\n\nThere's no problem that can't be solved by an extra layer of indirection.\n\nI'd take the advice of \"not writing for the implementation, but for the interface\" one further: write your code for Enumerables, not for Collections.\n\nAlso, if you're using C#, or Java 8, you should be using the functional facilities to generate values.\n\n Use Where to filter\n Use Select to generate new collections (that aren't, and might just be an iterator spitting out values from the existing one, but who cares? It'll return something you can't change)\n Etc.\n\nUse immutable collections\n\nCollections will be more involved.\n\nOr would, if you had to implement them yourself.\n\nFortunately, there are already libraries for <a href=\"https://msdn.microsoft.com/en-us/library/system.collections.immutable(v=vs.111).aspx\" target=\"_blank\">.Net</a> and Java for immutable collections.  These provide Add/Remove/etc methods which are not in place, and which return a new collection when you \"modify it\".\n\nBy doing this, even if we have a case like the one for the Fisher-Yates randomizer from part 1, you know nobody will mutate any collections it holds form under it, and invalidate any pre-calculated information it may be storing.\n\nThat's pretty much it\n\nBy doing these four things, and applying them with methodically, you'll see the benefits we have discussed and remove a whole class of errors.\n\nOr again, you can start using a nice, compact programming language that supports immutable data natively (along many other great features).\n\nWhere to do this?\n\nApplication logic\n\nUsing it on your business logic should be a no-brainer.\n\nWhether you have a monolith or a bunch of micro-services, you have a big layer where your business logic lives.\n\nLogic. Logic is about reasoning according to strict principles of validity. \n\nIt is about deriving what your next state should be, based on the last state and transformations that you are applying.  \n\nThere's nothing in that definition about keeping track of a whole bunch of independent but subtly inter-related states which may mutate from under you, and striving to minimize the collateral damage.\n\nMake your business logic handle immutable data.\n\nUI\n\nChances are anything that's UI related, which is effectively about encapsulating state, is going to be a pain with the current tools unless it has a degree of mutability (although approaches like re-frame do a great job of reducing mutability to a single point).  Those might not be as good a target, if the UI is simple.\n\nOr that's what I would have said some months ago.\n\nre-frame\n\nIs the GUI something that holds state? \n\nI'd actually argue that the GUI is something that represents and that we use to manipulate state.  \n\nYou're going to say potato/potatoe here, but stay with me for a moment.\n\nNow, we still have the word state in there. Where does this state come from?\n\nIf you have your entire application represented as immutable data, then that state is nothing but the last iteration of all the functions applied to the data that you use to build it. Said functions are triggered from the UI, but no UI component holds state itself.\n\nThis is the approach that re-frame, a ClojureScript library, uses. Even if you're not working in Clojure, or planning to work in Clojure, I recommend you give it a read. I'll have you thinking about UIs differently.\n\nDefold\n\nNow, you can be thinking \"well, that's all fine and dandy for web apps. If you're showing a couple of divs and a list, anything will do\".\n\nIf you're thinking that, I recommend this talk about how King.com used Clojure for their Defold game engine IDE to solve an entire host of problems that a mutable approach was causing.\n\nTheir implementation involves multiple components, each of which can have multiple inputs and have elaborate internal computations. \n\nTheir UI ends up represented as a graph of the data used to render it, which is then pulled by the UI rendering.\n\nSo apparently, it works the other way around.\n\nMutability is fine when you have two divs and a list, but after a certain level of complexity, immutability also makes your UI life easier.\n\nData layer\n\nThen there's your data storage. That sorta kinda needs to change over time, doesn't it?  Doesn't seem like a good target either.\n\nNot only there's Datomic already, but even if you can't switch databases right now, keeping immutability in mind when designing your system can help significantly.\n\nFor example, consider a system with a financial component. You have financial transactions, which may be deposits and withdrawals. Their status will change over time, from when they are created to when they're finally processed.\n\nDo you keep a single transaction record, with a Status column that you change every time the transaction is updated?\n\nI hope not.\n\nFor systems that are heavy on financial transactions, and where accountability is paramount, my usual approach is that we never mutate a transaction status.\n\nWhat we do instead is:\n Record the transaction status at every point in time;\n Have a materialized view that looks at the latest status;\n Define some statuses (Declined, Canceled, Executed) as final, after which a new status couldn't be recorded.\n\nIf you have ever done something like this, then you're effectively dealing with immutable data, because you can go back to your financial transaction as it was at any point in time, and see when its state changed. You can recover that world view.\n\nWhere not to do this?\n\nThat will actually be more of a question of environment, not of domain.\n\nIs RAM a concern? Say, are you making Android apps? Well, this will have a hit.\n\nIs raw performance a concern? For instance, are you doing a game, and altering a whole bunch of properties every frame?  You will be paying a GC hit as well.\n\nIn any of these cases, you'll need to do it judiciously. It's up to you to evaluate what judicious means.\n\nWhat's in it for you?\n\nReasoning\n\nEverything we do as developers is about trade-offs.  By using immutable data, we are trading off a slightly higher memory usage, and a potential garbage collection hit, so that we get a cleaner code base that is much easier to reason about.\n\nAnd I'm never going to get tired of saying this: code is read more than it is written.  A codebase that is easier to reason about is an asset that will continue to pay off.\n\nRefactoring\n\nYou'll have an easier time refactoring code.\n\nYou'll no longer have to wonder \"what's going on inside this method call? If I move it elsewhere, do I affect the result?\"\n\nAll that will matter is \"am I using this return value now?\" If not, you can move any and all operations that deal with it to where you think they better fit.\n\nSimplification\n\nMore importantly, you'll be writing code that's easy to delete. \n\nThe moment that you don't need a result value, for whatever reason, you can just delete whatever is used to calculate it... because you know that code can't possibly be having any other side effects that the application was relying on.\n\nOffloading processing\n\nIf you need to offload processing of a data item to a separate thread, you won't have to deal with locks.\n\nIf you need to offload processing of a data item to a separate _machine_, having had the discipline of keeping immutable data in the first place will make it much easier: you know _no computation in the system_ depends on a value that's being mutated elsewhere, so there's no reason why that computation needs to even happen on the same box.\n\nNo memory involved\n\nYou won't have to worry about who's holding your objects, or where else in the application flow they might be being changed.  \n\nIt doesn't matter, because it can't happen.\n\nNothing that you do with them will affect those other functions or objects... because nothing you do will actually touch values they might be holding.\n\nComprehension\n\nImmutable lets you focus on comprehension, not memory. When reviewing code, you'll be able to use your time to understand the operations involved, without having to keep mental track of invisible side effects.\n\nI keep making this point, which is not particularly popular since it's not an alpha-brogrammer kind of thing, but our brains suck. \n\nThey are limited. We forget things. We make assumptions. We get distracted. When we juggle a lot of things, we're going to drop a few balls.\n\nAll things considered, it's a wonder we manage to build the things we build.\n\nThe fewer assumptions your brain has to make, the fewer aspects of the codebase you need to memorize, the better off your entire team will be.\n\nConclusions\n\nAs counterintuitive as it might be, immutability lets you change your mind. It lets you change your mind about implementation details, about when processing is taking place, or even about where it's taking place.\n\nWe are too used to having to trust we are in control of our codebases. But if something can mutate, somebody will mutate it, and at that point you lose control.\n\nTo be in control of the code, you have to know how it behaves. Mutability demands you take things on faith.  Faith is at odds with knowing, and you need to know your codebase.\n\nIf you have been working in a purely object-oriented manner for a long time, it's time to get some new patterns into your brain. Make them functional ones, so they can help you replace trust with certainty.",
  "title": "Flexibility Through Immutability, part 2: How and When?"
}