Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Functional programming: immutability etc

I recently asked a question about functional programming, and received (good!) answers that prompted more questions (as seems to be the case with learning, sometimes). Here are a couple examples:

  1. One answer made reference to an advantage of immutable data structures: each thread can have its own copy. Now, to me, this sounds rather like a version control system (to use an analogy), where instead of locking code that someone has checked out so that it can't be modified by anyone else, everyone can check out their own copies. Sounds good. However, in VCS you have the concept of "merging" changes, in the case that two people changed the same stuff. It seems like this issue could certainly come up in a multithreaded scenario... so how is "merging" done when it's important that threads see the most recent data?

  2. This answer talked about the case where operations were being performed in a loop on an object, and how you can use a new object each time through instead of updating an old one. However, let's say the bankAccount is being updated in a non-loop scenario--for example a GUI banking system. The operator clicks the "Change Interest Rate" button, which fires an event that would (in C# for example) do something like bankAccount.InterestRate = newRateFromUser. I feel like I'm being dense here, but hopefully my example makes sense: there has to be some way that the object is updated, right? Several other things may depend on the the new data.

Anyway, if you can help me get my head around the paradigm shift, I'd be appreciative. I remember my brain going through similar "stupid phases" when learning OOP after a background of the simple procedural imperative approach to coding.

like image 760
J Cooper Avatar asked Dec 11 '08 21:12

J Cooper


1 Answers

Think about the String class in .Net (which is an immutable object). If you call a method on a string, you get a new copy:

String s1 = "there";
String s2 = s1.Insert(0, "hello ");

Console.Writeline("string 1: " + s1);
Console.Writeline("string 2: " + s2);

This will output:

string 1: there

string 2: hello there

Compare this behaviour to StringBuilder, which has basically the same method signature:

StringBuilder sb  = new StringBuilder("there");
StringBuilder sb2 = sb.Insert(0, "hi ");

Console.WriteLine("sb 1: " + sb.ToString());
Console.WriteLine("sb 2: " + sb2.ToString());

Because StringBuilder is mutable, both variables point to the same object. The output will be:

sb 1: hi there

sb 2: hi there

So, you absolutely cannot change a string once you've created it. s1 will always be "there" until the end of time (or until its garbage collected). That's important in threading because you can always step through each character and print its value knowing that it will always print 'there'. If you started printing the StringBuilder after it was created, you might print the first two characters of there and get'th'. Now, imagine another thread comes along ad inserts 'hi '. The value is now different! When you print the third character, it's the space from 'hi '. So you print: 'th there'.

like image 64
tsimon Avatar answered Sep 18 '22 16:09

tsimon