BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage News .NET Goes Immutable

.NET Goes Immutable

This item in japanese

Bookmarks

One of the most common misunderstandings in .NET development is the idea that variables of type IEnumerable or ReadOnlyCollection are thread-safe. Andrew Arnott of Microsoft explains,

If someone hands you a ReadOnlyCollection<T>, an IReadOnlyList<T>, or an IEnumerable<T> the only guarantee is that you can’t change the data – there is no guarantee that the person that handed you the collection won’t change it. Yet, you often need some confidence that it won’t change. These types don’t offer events to notify you when their contents change, and if they do change, might that occur on a different thread, possibly while you’re enumerating its contents? Such behavior would lead to data corruption and/or random exceptions in your application.

In order to offer truly thread-safe collections for scenarios where you would be tempted to use IEnumerable or ReadOnlyCollection, Microsoft’s Base Class Library (BCL) team is offering a preview of a new set of immutable collections. Based on techniques found in functional programming languages, methods that would normally mutate a collection will instead create new collections. Data sharing is possible between the old and new collection, allowing for some efficiencies.

An interesting characteristic of the immutable collections is that they don’t have a public constructor. Instead work always begins with ImmutableXxx<T>.Empty. Andrew writes,

Using a static Empty property is a departure from a well-entrenched pattern, and there is a reason for it. A constructor must allocate an object, yet given the immutability of these collections, a new object could only ever represent an empty list. Since mutating the collection creates a new collection, using a constructor would cause the creation of multiple objects to represent an empty list, which would be wasteful. A static property allows us to return an empty list singleton which all code in your app can share.

Builders and Collections

Building an immutable collection can be very expensive due to memory allocations. We already see this with strings, which are for all intents and purposes an immutable collection of char. To alleviate this the immutable collections will expose a ToBuilder method. This returns a builder object that can be cheaply modified. Once done, simply use the ToImmutable to get an immutable collection again.

Performance

Performance for immutable collections can be tricky. As you can see in the chart below, the order for most of the immutable collections is actually quite good. And it’s consistent, you don’t have to worry about tripping over the max size of a collection’s internal array which would trigger a full copy of the collection. And unlike normal collections, immutable collections will actually release unused space as items are removed.

But there is a cost. Each operation has to allocate another object in memory, which can strain the garbage collector. The biggest win is when you would otherwise be making snapshot copies of the collection anyways. But in the end the recommendation is still to “use the simplest code to get the job done and then tune for performance as necessary.”

This preview is available via the Microsoft.Bcl.Immutable NuGet package.

Rate this Article

Adoption
Style

Hello stranger!

You need to Register an InfoQ account or or login to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Community comments

  • Like in NextStep/Cocoa

    by Francisco Jose Peredo Noguez,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Finally, Microsoft has rediscovered that one needs to have mutable and immutable collections, just like NextStep/Apple did many year ago.

    I wonder when will Java finally rediscover this too...

  • Re: Like in NextStep/Cocoa

    by Jonathan Allen,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    I would be really interested in seeing a comparison between NextStep/Apple and .NET's implementation.

  • You could...

    by Muigai Mwaura,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Use F# and get immutable collections today.

  • Go for FSharpx and F# runtime in C#

    by Dario Iacampo,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    It is an interesting move for such a big elephant... anyway, I'd rather use the F# runtime simply importing a dll in the project. There is a framework that simplifies interaction between F# and C#: bugsquash.blogspot.it/2011/10/10-reasons-to-use...

  • Re: Like in NextStep/Cocoa

    by Clint Combs,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    You'll find "persistent" collections used extensively on the JVM in the Scala and Clojure ecosystems. Datomic (built on Clojure and the JVM) is a wonderful example in the database realm.

  • Re: Like in NextStep/Cocoa

    by Francisco Jose Peredo Noguez,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    You'll find "persistent" collections used extensively on the JVM in the Scala and Clojure ecosystems. Datomic (built on Clojure and the JVM) is a wonderful example in the database realm.


    This article is about "immutable" collections... why are you writing about "persistent" collections?

  • Re: Like in NextStep/Cocoa

    by Cameron Purdy,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    This article is about "immutable" collections... why are you writing about "persistent" collections?


    lmgtfy.com/?q=Persistent+data+structure

  • Re: Like in NextStep/Cocoa

    by Knox Liam ,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    I think you will find this article is as much about persistent data structures as pure immutability
    If you want something to be simply immutable you dont need to mention the techniques of data sharing.
    Scala supports structure that employ data sharing which are immutable. Java thirdparty libs such as Guava provide basic immutability.

  • Re: Like in NextStep/Cocoa

    by Faisal Waris,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    As others have said F#, Scala and Clojure all have persistent collections.

    F# also has structural equality which comes in very handy at times.

    For example "Set [1; 2] = Set [2; 1]" will evalute to true.

    This means that small Sets, Lists, Tuples, etc. can be used as dictionary keys which greatly simplifies your code in some cases.

    Structural equality can be an issue when comparing very large collections of course but alternatives exist.

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

BT