Home » Angular 2 » What if Everything Was Immutable?

What if Everything Was Immutable?

The first time a programmer who was trained in the classical procedural/object oriented history is confronted with the concept of making everything immutable, the first question that comes to mind is, “won’t that make my application slow?”  This is because of how most programmers have been trained.  Making everything immutable generally means that we must copy a lot of memory from one place to another.  Moving memory around is generally considered slow. And so, most programmers dismiss the whole idea as crazy talk.  But is it really all that crazy?

What if Everything Was Immutable?
Photo credit: Paul Stevenson via Visualhunt / CC BY

Two Paths

So, let’s look at some computer history.  If you’ve been in this industry any length of time, you’ve probably heard the name Turing and you know the Turing machine has something to do with programming.  But you may not know how it impacts your day to day programming life.

In short, Turing is the guy we can point to as the father of modern computing, complete with the fact that we generally process everything sequentially.  It is this sequential processing that causes us to have instructions working on memory and it has served us well.

But there is another branch of computer science that was made popular by Alonzo Church that is based on Lambda Calculus.  This branch of computer science is where the bulk of Functional Programming can be traced back to.  In this branch, everything is a function.  Any parameters you pass in cannot have their state changed and the value that is returned is a new value.

The main benefits to this newer functional style are:

  • If I pass in the same parameters, I’ll always get back the same value.
  • State is never mutated accidentally because state is never mutated.
  • Functions never have an unpredictable side effect.

Just think of how many bugs you wouldn’t have introduced into your code had this been true when you wrote it.

Convergence

Recently, functional programming has become more popular and the two branches of computer science have started to merge.  Taking the best of both worlds and using what makes sense from each.  But, we’ve already had at least one immutable object in most of our object-oriented languages.  The String object.  So, what does String give us that we use nearly every day?

Immutable Strings

No Side Effects

As we’ve already mentioned, that fact that something is immutable means it can’t be changed.  So, when you pass a string as a parameter, even though it is an object, the string won’t change if the function changes the string.  This is good news because the calling function doesn’t have to protect itself against unintended consequences.

Memory Efficiency

The other thing that happens with immutable object is that every string representation only exist once.  So, we never duplicate memory.

What do I mean by this?

Well, take this example from C#

var string1 = "abc";
var string2 = "abc";

if(string1 == string2){
  writeLn('is equal');
}

Testing Equality

string1 and string2 point to the same object “abc” not two different instances of “abc”.  This is why we can write string1 == string2.  Unfortunately, the == operator is overloaded so we are still doing string comparison.  But if you want efficiency, you can use the Intern() method and ReferenceEquals() to bypass this overload and use pointer comparison.  This is a good thing because we test for string equality and inequality so often the performance penalty we incur from making strings immutable is more than offset by the performance gains we get testing for equality.

Make Everything Immutable

If you think about the code you typically write, how much of the time would you benefit from every object in your code working in a similar way to strings?

Wouldn’t it be a great thing if you knew that when you passed an object into a function, that function was not going to change the object at all?  Can you think of times that might have prevented a bug?

Think of the memory optimizations you would benefit from.

And how much easier would it be to test for equality if all you had to test was a memory pointer?  Not only would it be fast, but it would be reliable and a lot less work to code.

Immutability is Hard – or is it?

So now that you know what the benefits are, you are probably thinking, “Yes, but coding immutability into a language that doesn’t support it natively is a lot of work.  It is so much easier to write code the way I always have, even if it isn’t quite a safe.”

Yes, I feel your pain.  But there are libraries for that.  Say you could get all the benefits of immutability with very little programming or performance cost?  Would you be interested?

I know I was.  Just having the benefits of immutable data with the performance was benefit enough for me.  But then I was introduced to immutable.js and I realized that I could have all of the benefits with a lot less performance cost than I was expecting because the library uses data structures that allow us to manipulate pointers rather than raw data.  The result is that only pointers to data that have actually changed change.  Nearly everything else stays as it was and adding items to List instead of arrays and Maps ends up being a lot more efficient.

Impact on Angular2

By using immutable object in Angular2 along with libraries like NgRX/Store you can see some major performance increases because the view will be able to determine when it needs to change based on simple object pointer comparison rather than checking entire objects.  For compute-intensive tasks, this is going to be a huge benefit. But it is also well worth learning how to use this before you ever need it simply because it will be a new way of thinking about your project that may take some time to get accustomed to.

 

Other post in Angular 2
Summary
Article Name
What if Everything Was Immutable?
Description
The first time a programmer who was trained in the classical procedural/object oriented history is confronted with the concept of making everything immutable, the first question that comes to mind is, “won’t that make my application slow?” This is because of how most programmers have been trained. Making everything immutable generally means that we must copy a lot of memory from one place to another. Moving memory around is generally considered slow. And so, most programmers dismiss the whole idea as crazy talk. But is it really all that crazy?
Author
DMB Consulting, LLC

Related Post

  • Dissecting Angular 2 ModulesDissecting Angular 2 Modules In the new world of Angular 2, and even in the world of Angular.js, you might feel like the concept of a module is the most difficult to wrap your head around. This is especially if you’ve […]
  • Angular 2 ThoughtsAngular 2 Thoughts I was asked this past week what my thoughts were on Angular 2.  I wrote early on about my impressions of Angular 2 when it was barely done enough to review.  But now that I’ve been working […]
  • Adding CSS and JavaScript to an Angular 2 CLI ProjectAdding CSS and JavaScript to an Angular 2 CLI Project In the last post, we looked at how to create an Angular 2 project using the Angular CLI.  Today we want to look at how to manage CSS and JavaScript to our Angular 2 CLI […]
  • Awesome Angular2 Architecture Options and OpinionsAwesome Angular2 Architecture Options and Opinions On the subject of Angular2 Architecture, the perception is that Angular 2 is a highly-opinionated architecture.  But even though there is a style guide for Angular 2, there are a lot of […]
  • Unit Testing an Angular 2 CLI ProjectUnit Testing an Angular 2 CLI Project This week we want to continue our series about Angular 2 by looking at the Unit Testing capabilities that Angular 2 provides for us.  What we want to cover today is: Tweaking Karma to […]

About Dave Bush

Dave Bush is a Full Stack ASP.NET developer focusing on ASP.NET, C#, Node.js, JavaScript, HTML, CSS, BootStrap, and Angular.JS. Does your team need additional help in any of the above? Contact Dave today.

  • csmager

    Good article! I have one niggle, though. In C#, the == operator for strings is overloaded and does not compare using reference equality. ‘Every string representation only exists once’ is not correct; the CLR does string interning for string literals, but not strings you create at runtime. See this fiddle for a demo illustrating the point: https://dotnetfiddle.net/hawc0w

  • Large data is generally going to be an issue regardless of which strategy you use. In the case of the guy who says he tried this with 22meg of data, I would imagine it took a while to return the data. In the case of 55,000 rows, I don’t expect any major performance difference, especially if you are using a library optimized for immutable javascript.

  • Tom

    This is an interesting article and I’ve had this discussion a few times and I quite like the concept. The problem I have always found is that it’s fine for a simple example where all of your properties can be set on the constructor initialisation. But if a model has a large number of properties and is used by many different processes which all update it in different ways, you end up with lots of extra methods (and lines of code) writing explicit update methods and constructors as you cannot access the setter methods.

    This might be a result of a bad design of the domain, or I’m misunderstanding the implementation, but large complicated models are common in every company I have worked for.

    • Using a Flux pattern with either NgRX/Store or Redux, I don’t think you will experience the problems you have communicated any more than you would when updating multiple tables in a database.

  • Where I get stuck with this is testing. I pretty commonly test by creating an object, doing stuff, then checking to see if the same object has changed to reflect whatever I did to it. So now I have to change a lot of my testing strategies at the same time as I’m learning all the other things that are involved in learning Angular 2. When you need to get things done, sometimes you need to trade off “yes, that’s great in theory, but in practice I need to limit the amount of new, intersecting, concepts or I won’t ever finish anything.”

    So Immutables and by extension the more complex Observables that require them will have to wait for another day.

    • Yes, this pattern does take a bit of re-learning. But imagine what it would be like if you invested the time to learn it.

      • Sure, and it would be great to know everything ever. I’d love to know more about particle physics. A law degree would be nice.

        But at some point you have to say this is what I know right now. I think it will get easier when Angular 2 gets better documented and you can’t get completely detailed for hours over an error message that gets no relevant hits on Google and when (hopefully) it doesn’t take so long for tests to compile and run that you can sit there for quite a while and not know Karna crashed.

  • The feeling I kind of get looking at how the Immutable collections I’ve looked at work is that you create a “new” large object that’s made up of all the original smaller objects except the one small object that changes. I personally find it easier to reason about large objects that change over time than large objects that get replaced every time something happens. Imagine if your car was replaced every time you put on the brakes with a new car that contains all the original parts except a new set of brakes in a different state.