Does (or will) C# include features for side-effects verification?

Joan Venge picture Joan Venge · Feb 27, 2009 · Viewed 14.3k times · Source

I know C# is getting a lot of parallel programming support, but AFAIK there is still no constructs for side-effects verification, right?

I assume it's more tricky now that C# is already laid out. But are there plans to get this in? Or is F# the only .NET language that has constructs for side-effects verification?

Answer

Judah Gabriel Himango picture Judah Gabriel Himango · Feb 27, 2009

C# the language isn't, but .NET the framework may be.

The Contracts library + the static analysis tools being introduced in .NET 4 might introduce these:

Microsoft is using [Immutable] and [Pure] inside .NET 3.5 framework right now.

For example, see [Microsoft.Contracts.Immutable] and [Microsoft.Contracts.Pure] inside .NET 3.5, in the System.Core.dll. Unfortunately, they're internal. However, Microsoft.Contracts.* is mostly born out of Spec# research, and Spec# has been folded into the Contracts APIs that will be part of .NET 4.0.

We'll see what comes of this. I haven't checked to see if the pre-release .NET 4.0 bits contain any APIs like [Pure] or [Immutable] in the Contracts APIs. If they do, I'd imagine the static analysis tool will be the one to enforce the rule, rather than the compiler.

edit I just loaded up Microsoft.Contracts.dll from the latest pre-release drop of MS Code Contracts this week. Good news: [Pure] and [Mutability(Mutability.Immutable)] attributes exist in the library, which suggests they will be in .NET 4.0. Woohoo!

edit 2 Now that .NET 4 has been released, I looked up these types. [Pure] is still there in System.Diagnostics.Contracts namespace. It's not intended for general use, but rather, for use with the Contract API's pre- and post-condition checking. It is not compiler enforced, neither does the Code Contract checker tool enforce purity. [Mutability] is gone. Interestingly, where Microsoft was using Mutability and Pure attributes in .NET 3.5 (in the internal BigInteger class in System.Core.dll), .NET 4 has moved BigInteger into System.Numerics, and has stripped the [Pure] and [Mutability] attributes off that type. Bottom line: it appears .NET 4 does nothing for side-effects verification.

edit 3 With the recently (late 2011) previewed Microsoft Rosyln compiler-as-a-service tools -- believed to be scheduled for RTM in Visual Studio 2015 -- look like they'll be able to support stuff like this; you could write extensions to the compiler to check for purity and immutability, and issue compiler warnings if something decorated with those attributes don't follow the rules. Even so, we're looking at a few years out to support this.

edit 4 Now that Rosyln is here as of summer 2015, the ability to build a compiler extension for pure/immutability does indeed exist. However, that doesn't do anything for existing framework code, nor 3rd party library code. But on the horizon is a C# 7 proposal for immutable types. This would be enforced by the compiler and would introduce a new immutable keyword to C# and a [Immutable] attribute in the .NET framework. Usage:

// Edit #4: This is a proposed design for C# 7 immutable as of June 2015.
// Compiler will implicitly mark all fields as readonly.
// Compiler will enforce all fields must be immutable types.
public immutable class Person
{
    public Person(string firstName, string lastName, DateTimeOffset birthDay)
    {
        FirstName = firstName; // Properties can be assigned only in the constructor.
        LastName = lastName;
        BirthDay = birthDay; 
    }

    public string FirstName { get; } // String is [Immutable], so OK to have as a readonly property
    public string LastName { get; }
    public DateTime BirthDay { get; } // Date is [Immutable] too.
}

edit 5 It's November 2016, and it appears immutable types were dropped from C# 7. There's always hope for C# 8. :-)

edit 6 It's November 2017. C# 8 is coming into full view, and while we won't have pure functions, we will have readonly structs. This makes a struct immutable, which allows several compiler optimizations.

edit 7 It's July 2020, and C# 9 is coming with support for records, which are fully immutable types. Additionally, records will have With expressions for creating new records from existing records to represent new state.