Partial updates in an immutable World

This post was prompted by a conversation with a good friend, who is an experienced Java developer taking their first, tentative, steps towards becoming a Scala programmer. Basically, the conversation went as follows:

“…Immutability seems good and like a goal I should aim for. How can I get this in my domain objects without having to provide a multiplicity of constructors to do partial updates ? Is it really that big a deal ? I’ve rarely had to worry about this stuff in Java at all !”

Both fair question, which I’ll try to address in the remainder of this post.
I find the first query on object creation having some relation to having clearly defined idioms and best practises in Scala, with the answer being blurred by the plethora of techniques for creating new object instances in Scala. Cutting to the chase, the appropriate solution to this scenario is to use default and named parameters, (a feature which has been in Scala since v2.8, but blink and you might have missed them). I’ve included a code sample below and this approach, [basically], leverages the fact that the caller is issuing an update to an instantiated class in the appropriate context. This allows for updating of only the attributes that have been explicitly named and passed in to the function. This also encourages the fluent builder style, whereby mutations and operations over the domain object can be chained together to form a pipeline of transformation.

 case class Person(val firstName: String, val lastName: String, val age: Int, val email: String) {
  def update(firstName: String = firstName, lastName: String = lastName, age: Int = age, email: String = email) : Person = {
   Person(firstName, lastName, age, email)
  }
 }
 
 val seedPerson = Person('A', 'B', 1, 'me@home.com')
 println(seedPerson)
 
 val updatedPerson = seedPerson update (age = 100, firstName = 'Z')
 println(updatedPerson)

Note, this isn’t the only approach to performing partial updates, as similar results could also be achieved using a reflection [though at the expense of static type checking support], or using extractors, [which would likely be more verbose due to the lack of context], or even using zippers, tree rewriting or lenses ! (depending on how deep and object graph you need to update, and whether the requirements dictate updating all items in the object graph based on a regex/pattern match).

So, to the question of whether you need immutable data objects. I see this as being a follow up question to the broader issue of whether you actually want or need concurrency at all. Arguably, at different ends of the ‘enterprise‘ spectrum, support for concurrency is not appropriate. For example, in low latency, high transactional systems (where execution is typically single threaded to avoid the cost of context switching) and in single user embedded devices (where resources and interaction levels are constrained) concurrency is eschewed due to the non functional requirements. Also, certain business models do not need to cater for concurrent execution, such as ‘his is partitioned publisher‘ scenarios (where idempotency is important, but not concurrency).

Having said that, (and somewhat tautologically) concurrency problems are generally a problem when they’re a problem. Depending on the profile and semantics of the program, a system could run for some time before any issues arise. However, when you encounter a concurrency bug, like when Jon and Mrs. H met in Hart to Hart, it can be murder. Ultimately, if you’re going to either want or need concurrency guarantees over your domain, immutability is one option and using Scala’s default and named parameters removes much of the boilerplate pain of the implementation. It’s hard to say no to something for [close to] nothing, (something I’d informally termed the L’Oreal principle).

A final observation with this approach is that updating collections still need custom handling to capture the semantics of what the ‘update’ is expected to achieve.

Hopefully this post will help others moving to Scala and trying to tackle the challenges of the functional paradigm.

Happy hacking !

Reference: Partial updates in an immutable World from our JCG partner Kingsley Davies at the Scalabound blog.

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

JPA Mini Book

Learn how to leverage the power of JPA in order to create robust and flexible Java applications. With this Mini Book, you will get introduced to JPA and smoothly transition to more advanced concepts.

JVM Troubleshooting Guide

The Java virtual machine is really the foundation of any Java EE platform. Learn how to master it with this advanced guide!

Given email address is already subscribed, thank you!
Oops. Something went wrong. Please try again later.
Please provide a valid email address.
Thank you, your sign-up request was successful! Please check your e-mail inbox.
Please complete the CAPTCHA.
Please fill in the required fields.

Leave a Reply


× seven = 14



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close