71

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?

StayOnTarget
  • 11,743
  • 10
  • 52
  • 81
Joan Venge
  • 315,713
  • 212
  • 479
  • 689

3 Answers3

173

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.

edit 8 It's November 2021, and C# 10 has been released with support for With expressions for structs, as well as record structs. These also aid in the creation of immutable types.

Judah Gabriel Himango
  • 58,906
  • 38
  • 158
  • 212
  • 1
    Another note, as of this week's prerelease drop, [Pure] is public, but [Mutability(...)] is internal. We'll see if this changes. – Judah Gabriel Himango Mar 01 '09 at 03:17
  • Another thing to note is whether these attributes are meant for general use, or if they're intended only for use in the contracts APIs. I would hope they are generally useful to be used throughout a codebase, regardless of whether one is utilizing the actual System.Diagnostics.Contract APIs. – Judah Gabriel Himango Apr 14 '09 at 17:27
  • 74
    +1 for updating the answer to an ancient question when the world changed. – Emile Aug 18 '10 at 15:24
  • 2
    @BartoszKP Really? I find that very helpful--each edit indicates a point in a timeline, and that timeline is still important and relevant because older versions of the C# compiler are still in use (for instance I'm working on a project that, for some reason, can only be compiled in MSVS 2013). – Kyle Strand Apr 18 '17 at 17:05
  • @KyleStrand Then perhaps partitioning the answer with headers that explicitly state the C#'s version is in order, or composing this all together in a consistent way (i.e. "version X had immutables planned, but in Y they were left out"). The fact that these pieces of information result from an "edit" is completely irrelevant. – BartoszKP Apr 18 '17 at 19:09
  • 1
    @BartoszKP It may not be optimal, but I don't think it's "polluted". – Kyle Strand Apr 18 '17 at 19:09
  • @KyleStrand Technical details on how the answer was created are not the point - if not pollution, they are noise, distraction, heresy, etc. ;) – BartoszKP Apr 18 '17 at 19:18
  • The data keyword in C#9 that indicates records might be the latest update in this story. – Sorrien May 22 '20 at 14:04
  • Are there any third-party code analysis tools that can verify if `[Pure]` functions are indeed pure? – Aaron Franke Aug 25 '21 at 14:52
17

Not only is there nothing for side-effect verification - there's nothing even to verify that a type is immutable, which is a smaller step along the same route IMO.

I don't believe there's anything coming down the pipe in C# 4.0 (although I could easily be wrong). I really hope that immutability makes an impact in C# 5.0; certainly Eric Lippert has blogged quite a bit about it, and folks at MS have been thinking about parallelism a fair amount.

Sorry it's not a more encouraging picture.

Edit: Judah's answer is considerably brighter... would framework support be good enough for you? :) (I wouldn't be entirely surprised if some aspects of Code Contracts weren't ready for .NET 4.0, mind you - if perhaps they kept the initial release relatively small and boosted it later.)

Community
  • 1
  • 1
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Thanks Jon. Your insight is always welcomed :) I justed wanted to see what is going on on that department. – Joan Venge Feb 26 '09 at 23:42
  • 1
    Views welcome on whether this answer is still useful or whether it should be deleted in the light of Judah's. Happy to delete it if appropriate. – Jon Skeet Feb 26 '09 at 23:52
  • I would really like it if the Runtime would guarantee pureness and immutability, just like it does for type safety. That way you could build a pure language on top of the CLR and safely call (or be called from) C#. – Tom Lokhorst Feb 26 '09 at 23:53
  • @Jon: I think your reply is still useful. – Joan Venge Feb 26 '09 at 23:55
  • I think your reply is still useful. I just updated my reply to include newfound information: it appears .NET will have System.Diagnostics.Contracts.PureAttribute and System.Diagnostics.Contracts.Mutability attributes. VS2010 will come with a static analysis tool integrated to enforce purity, etc – Judah Gabriel Himango Feb 27 '09 at 18:43
14

In principle, verifying whether something is immutable & whether the code lacks side-effects is easy. All fields of the class/data structure must be readonly and their type must be another immutable object. We'd also need a way for marking a delegate as "pure" (side-effect free), but that would probably all be possible.

However, the problem is that this is often too restrictive. In F#, you'd generally write the code in a side-effect free & immutable style, but it is often beneficial to use some mutation locally. This doesn't break the overall purity (in some sense) and makes it much easier to write the code. However, verifying this automatically is difficult (meanin that it's an interesting theoretical problem..)

For example, it's perfectly fine to work with arrays in a "pure" way. You can have methods like Array.map that apply some function to all elements and return a new array without modifying the original one. The function mutates the (newly created) array before returning it, but the array isn't mutated anywhere else, so this is in principle pure, but hard to verify (and this is quite useful programming pattern in F#).

So, I think there is a lot that could be done, but simply banning all side-effects may not be as good way as it appears to be. The nice thing about contracts is that they could be probably used in this scenario as well.

Tomas Petricek
  • 240,744
  • 19
  • 378
  • 553