I suggest you ...

Support for immutable objects

Use some ideas of F# for C#. For instance, it would be very nice to have support for immutable objects, like immutable lists etc. with low costs for list changes. Also, a keyword to declare a class explicit as immutable would be helpful.

164 votes
Vote
Sign in
Check!
(thinking…)
Reset
or sign in with
  • facebook
  • google
    Password icon
    I agree to the terms of service
    Signed in as (Sign out)
    You have left! (?) (thinking…)
    Dirk Lellinger shared this idea  ·   ·  Flag idea as inappropriate…  ·  Admin →

    12 comments

    Sign in
    Check!
    (thinking…)
    Reset
    or sign in with
    • facebook
    • google
      Password icon
      I agree to the terms of service
      Signed in as (Sign out)
      Submitting...
      • Qwertie commented  ·   ·  Flag as inappropriate

        Enhanced C# (LeMP) supports "alt class", a quick way of making immutable objects and disjoint unions:

        public alt class Rectangle {
        . alt this(int X, int Y, int Width, int Height);
        . public Size Size {
        . . get { return new Size(Width, Height); }
        . }
        }

        public abstract alt class BinaryTree<T> where T: IComparable<T>
        {
        . alt Leaf(T Value);
        . alt Node(T Value, BinaryTree<T> Left, BinaryTree<T> Right);
        }

        More info: http://ecsharp.net/lemp/pattern-matching.html#algebraic-data-types

        You also asked for "immutable lists etc. with low costs for list changes". The Loyc.Collections library (LoycCore on NuGet) provides what you're looking for:

        - VList<T> is an immutable list that works like a hybrid between persistent linked lists in functional languages and a regular .NET list class (it implements IList<T>).
        - There are other persistent data structures such as a pair of immutable hash trees: `Set<T>` and `Map<TKey, TValue>`
        - And there's other handy features, like slices (references to parts of larger lists).

        To learn more visit http://core.ecsharp.net/ or http://core.ecsharp.net/collections/

      • verelpode commented  ·   ·  Flag as inappropriate

        We all know that immutable objects are very good in some situations. But how to build the immutable object? If the class contains only few properties, then a generally satisfactory solution is to pass all the properties as parameters in the constructor.

        However, this solution is impractical when a class contains many properties. A constructor with 20 parameters is impractical.

        Imagine a source code generation facility that automatically generates (and maintains) mutable "builder" (AKA "factory") versions of selected classes! It would inspect the properties of each immutable class (getter-only properties) and generate a "builder" version with the same properties except with both getter and setter methods in each property.

        It must also support collection properties. The immutable class efficiently stores each list-collection property as a fixed-size array, like this:

        private Something[] _SomeItems;
        public IReadOnlyList<Something> SomeItems { get { return _SomeItems; } }

        Whereas the builder version implements the collection property in a mutable manner like this:

        private List<Something> _SomeItems = new List<Something>();
        public IList<Something> SomeItems { get { return _SomeItems; } }
        // (still no setter, instead use IList.Add() etc.)

        IMPORTANT: I said generate the builder from the immutable class, but consider whether the opposite direction would be better. i.e. should the programmer write the builder version of the class, then the immutable version is auto-generated from the builder class. Or maybe support both directions -- programmer's choice.

        ***** ACTUALLY: The best solution may be that the programmer writes NEITHER the immutable or builder version, rather he/she writes an abstract class or interface that is used as the basis/source to auto-generate both the immutable and builder versions of the class. Perhaps the programmer can optionally override the auto-generation of a particular property implementation in either the immutable or builder class (or both) by supplying a manually-implemented version of that property (in special cases), but the default and usual situation is to auto-generate the implementation. *****

        Alternatively, you could consider some kind of new C# syntax/feature that extends the preexisting "Object Initializers" feature to better support immutable classes:
        https://msdn.microsoft.com/en-us/library/bb384062(v=vs.140).aspx

        See also the following proposal, but I still don't think it's sensible to have a constructor with 20 parameters. The opposite direction would actually be more justifiable (if at all) -- perhaps auto-generate a constructor from properties, but certainly don't auto-generate properties from a constructor.
        http://roslyn.codeplex.com/discussions/543522

        (A bad solution: Make a constructor in the immutable class with a System.Dynamic.ElasticObject parameter, then construct the immutable object by reading the contents of the ElasticObject. This is a bad idea because it prevents IntelliSense and compile-time reporting of mistakes. It's also inefficient.)

        Thanks for considering it.

      • Chris McKenzie commented  ·   ·  Flag as inappropriate

        A good immutable syntax for classes or structs should allow property assignment via object initializers (kind of like how readonly fields are settable in the constructor and at declaration time). Once the instance is created it's properties/fields should be readonly.

      • Martijn Hoekstra commented  ·   ·  Flag as inappropriate

        @Marcel Roma addition of an immutable ro readonly keyword for a struct/class that would be syntactic suger for readonly on all the types fields would be a (nice) language addition though.

      • Marcel Roma commented  ·   ·  Flag as inappropriate

        There's a nice video on channel9 about the new immutable collections (BCL preview). Erik Meijer, Immo Landwerth und Andrew Arnott talk about the internals of ImmutableStack<T>,
        ImmutableQueue<T>, ImmutableList<T> et.al. and the performance gains they brought in.

        http://bit.ly/14OHUjm

        The addition of immutable collections is however not a language feature. It's more of a clever mashup of pre-existing classes and language features.

      • Mark Adamson commented  ·   ·  Flag as inappropriate

        Personally I'd be fine without the simple way to add list items. I think that could come later if there were a natural and safe way to do it.

      • Mark Adamson commented  ·   ·  Flag as inappropriate

        I would like it a. a readonly keyword for classes and interfaces, and have the compiler enforce it all the way down the field references and field types i.e. they would all need to be marked readonly to compile

      • Qwertie commented  ·   ·  Flag as inappropriate

        I suspect that you want some special syntax for immutability, but FYI...

        I made an immutable data structure called VList that 'abuses' structures in order to provide references to an immutable list, but you still use methods like "Add" to give the appearance of modifying the list in-place: http://www.codeproject.com/Articles/26171/VList-data-structures-in-C

        This works okay, but it would work better with a little compiler support. In particular, when a property returns an immutable list, C# will not prevent you from "modifying" it:

        VList<int> MyList { get; }
        Foo.MyList.Add(item); // has no effect: the item is added to a COPY of MyList

        This would be easily fixed if the compiler would recognize a [Mutates] attribute on Add().

        [Mutates] public void Add(T item);

        I propose that this attribute would cause a method to be treated exactly like a property setter, i.e. the compiler would only allow you to call Add() on a *variable*, not a *value*.

        Right now I am working on a new (mutable) list data structure. It will support O(1) cloning and freezing, which is a nice compromise between immutability and high performance. it will be called the "A-List" or "all-purpose list". Coming soon to a CodeProject near you.

      Feedback and Knowledge Base