Immutability - something worth striving for
Richard Wood
Posted on November 30, 2018
When I worked in C# at PartsTrader I started to see the similarities between what Domain Driven Design is looking for and what Functional Programming does. Or rather what FP has to do to be able to be useful in the real world.
I currently develop in Javascript for one client and functional language Elm for another. I've previously worked for two .Net companies. One of them - PartsTrader - was dead keen on DDD.
So I'm talking about separating out pure functions from side effects. In DDD the idea is to circumscribe business logic, keeping all the IO and external interfaces outside the circle.
Whamo, when you look at a functional environment such as Elm, you have all the pure functions segregated away from the messy IO and external javascript functions.
The difference is that in Elm this split is mandatory. In DDD and object oriented languages it's a voluntary design decision with some serious book reading available to convince you that you are doing the right thing lol.
However, it still comes back to immutability. Functional programming gives you this off the bat. In non-functional languages it is still a great idea, but you have to choose to do it. The benefits are that your code is easier to debug as what goes in and comes out remains constant at every level.
In Elm the entire code is immutable - think of it as one big function that is called as needed. Anything side-effecty will be done by the runtime and then the function called again.
This has some interesting benefits. If you want to see what your programme is doing, just look at the big 'update' function that is at the bottom of this tree and anything it delegates it to. With the strict typing on top of that, if you make any changes that disrupt things you find out very quickly on compile, and the error messages just 'know' so much about what you are doing.
Which is not to disparage .Net's Visual Studio when using C#. It 'knows' a hell of a lot before you even get to compile thanks to the work that has gone into it over the years from some very smart people.
In non-functional languages it is also good practice to pass in any values that may change randomly so that you still have unit-testable functions - dependency injection. In Elm, functions that call side effects don't return things back into the code and so don't impact the return value. They go off to the runtime, which then returns values through the message update channel as if some magic fairy generated them.
Anyway, developing in Javascript is where the rubber hits the road for this discussion. On the one hand it is a functional language in that functions are first class and references to them can be passed around. On the other hand it is so loose that you can have side effects wherever you like. You really don't know with some functions what might come out the other end. Tightening that up requires a fair bit of overhead construction.
I am working on an old JS code base that I've largely converted to ES6. While I've brought in Webpack, I've shied away from introducing any of the new frameworks like React and Angular - both of which I have used before. I use a bit of native JSX as a short cut for templating forms and menus, but that's another story.
With ordinary JS you can still take a strategy of making things as immutable as possible. Again it means segregating out anything that is a side effect until your functions become pure.
In my case I'd like to start to reorganise the codebase so that, well, it looks more like an Elm structure with a tree of update logic updating a model and a set of view functions that simply reflect the changes in the model - all as pure as possible. I'm still working through how best to do that in combination with the heavy use of Mapbox and Leaflet in the app.
There are also times in the nitty gritty when imperative code in Javascript is just easier to understand and quicker to achieve, and being pragmatic is certainly a good quality. Perhaps best to leave a comment in such functions that they should not be extended into incorporating side effects and make sure not to pass anything external in.
I believe that immutability and segregation of side effects is one of the core goals worth striving for in software design. If it can't be achieved immediately it should at least be regarded as the preferred direction.
I am confident that by taking this approach something easier to read, maintain and add to will come of it.
Posted on November 30, 2018
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.