A C# library to write functional code – Part III – Records

Other posts in the series:


  • Part I – Background
  • Part II – Tuples
  • Part III – Records

  • Part IV – Type Unions

  • Part V – The Match operator

  • Now that we know what Tuples are, we can start talking about Record, as they use a derivative of Tuples under the cover. But first, what is a record?


    Well, in C# parlance a Record is a sort of immutable value object. I talked at length about these fellows in this series of blog posts. In functional parlance, a Record is a Tuple that lets you access its items by name.


    You code Records like this:

        public class Order: Record<string, int> {

    public Order(string item, int qty): base(item,qty) {}

    public string Item { get { return state.Item1;}}
    public int Quantity { get { return state.Item2; } }
    }

    public class Customer: Record<string, IEnumerable<Order>> {

    public Customer(string name, IEnumerable<Order> orders) : base(name, orders) { }

    public string Name { get { return state.Item1; } }
    public IEnumerable<Order> Orders { get { return state.Item2; } }
    }


    You need to do three things:



    1. Inherit from a generic Record class specifying the types of the properties as parameters

    2. Add a constructor that calls back to the Record constructor

    3. Add getters to retrieve the values of the properties (no setters as it is immutable)

    This may seem like plenty of work, but in return you get structural equality. Coding that by hand every time you use a record would be a royal pain. You lose control of the base class, but that is often not a problem as in functional-land you more often use type unions than inheritance.


    How is it implemented?


    First of all it is an abstract class with as many generic parameters as properties that you need in your Record. Let’s use two as an example.

        public abstract class Record<T1, T2> {

    This abstract class has a field of type STuple:

            protected readonly STuple<T1, T2> state;

    What is a STuple? Well it is exactly the same as the Tuple described in Part II, but coded as a struct instead of a class. The reason to use a struct is to not allocate an additional object on the stack. This allows this solution to be as ‘performant’ as simply having coded the fields on the class itself. Or at least I think so …


    The Record class also has a constructor that simply initialize the STuple:

            public Record(T1 t1, T2 t2) { state = F.STuple(t1, t2); }
    where
            internal static STuple<T1, T2> STuple<T1, T2>(T1 t1, T2 t2) {

    return new STuple<T1, T2>(t1, t2);
    }


    The Equals method is very much the same as the Tuple’s one, just delegating to the same DSEqual function that checks equality for Tuples.

            public override bool Equals(object right) {

    Utils.CheckNull(right);

    if (object.ReferenceEquals(this, right))
    return true;

    if (this.GetType() != right.GetType())
    return false;

    var rightT = right as Record<T1, T2>;

    return F.DSEquals(this.state, rightT.state);
    }

    That’s it. Not too difficult as most of the implementation is based on the Tuple’s code. Next post will hopefully be more interesting. It is about Type Unions.

    Advertisements

    A C# library to write functional code – Part II – Tuples

    Other posts in the series:


  • Part I – Background
  • Part II – Tuples
  • Part III – Records

  • Part IV – Type Unions

  • Part V – The Match operator

  • Tuples are a way for you not to name things. In Object Oriented languages you got to name everything. If you need to represent a bunch of data, you create a class for it.


    There is a strange asymmetry in mainstream OO languages in that you can pass multiple parameters to a function, but you can return just one value. Granted, there are ways around it: you can use ‘ref’ in C# or return some sort of collection where things are stored. But by and large the model is: you pass many, you get one; if you need to return more than one, create a class to represent this ‘bunch of data’. Tuples are a way for you not to create such a class.


    Tuples are also much more than that. Once you have the language concept of ‘a bunch of data without a name’, you can create arrays of them, you can pass them as parameters, use them as local variables. Wherever you’d use a type, you can use a Tuple instead.


    This is particularly appealing to me as I like to use classes almost exclusively to represent things that have a counterpart in the domain I’m modeling (i.e. Customer, Account). I don’t like to create classes/structs just for the sake of temporarily put some data together.


    You can create your own Tuple class in C#, but the syntax gets ugly. Syntax matter. Syntax helps you to think differently about your program. We have syntax for anonymous types, but given that they cannot escape the scope of a method, they cannot be used as full replacement for Tuples.


    In any case, to my implementation. Here is how you create a Tuple:

                var t1 = F.Tuple(34, “bo”, 2.3);

    not too bad. In F# it is better: (34, “bo”, 2.3). And you often don’t need the parenthesis. But still, my C# version is ok.


    You then need to access its elements:

                var n = t1.Item1;
    var s = t1.Item2;

    In F# you usually access them by doing pattern matching, which gives a more intuitive syntax. But again, my C# syntax is not terrible. 


    Tuples need to have structural equality, which means that the following has to work:

            ArrayList mad1 = new ArrayList { new List<IEnumerable<string>> { new string[] { “bo” }, new string[] { “bo” } },
    32, “bo”, new int[] { 4, 5, 6 } };
    ArrayList mad2 = new ArrayList { new List<IEnumerable<string>> { new string[] { “bo” }, new string[] { “bo” } },
    32, “bo”, new int[] { 4, 5, 6 } };
    ArrayList mad3 = new ArrayList { new List<IEnumerable<string>> { new string[] { “bo” }, new string[] { “bo” } },
    32, “bo”, new int[] { 4, 5, 5 } };
            Assert.AreEqual(F.Tuple(mad1, mad2, mad1), F.Tuple(mad2, mad1, mad2));
    Assert.AreNotEqual(F.Tuple(mad1, mad2, mad1), F.Tuple(mad1, mad3, mad1));

    You can use Tuples as return values, parameters, locals etc. Unfortunately, the syntax is ugly when Tuples are part of the signature of a function:

        public Tuple<string, IEnumerable<Tuple<string, ObservationHistory>>> Execute() {

    }


    With the above information, you can be a user of Tuples. From this point on, I’ll talk about some details of the implementation (I also attach the full code to this post as a zip file).

        public class Tuple<T1> {

    public Tuple(T1 t1) {

    Item1 = t1;
    }

    public readonly T1 Item1;

    #region Equals, GetHashCode, ==, !=
    }

    public class Tuple<T1, T2> : Tuple<T1> {

    public Tuple(T1 t1, T2 t2) : base(t1) { Item2 = t2; }

    public readonly T2 Item2;

    #region Equals, GetHashCode, ==, !=
    }


     


    So, Tuples are classes, not structs. The reason for it is fully described in this series of posts. They also inherit from one another. There are pros and cons to that. The main pros are that I had to write less code and that you can pass a Tuple<int, string> when a function expects a Tuple<int, string, int>. The main drawback is that you can pass a Tuple<int, string> when a function expects a Tuple<int, string, int>.  Also notice the use of public fields. These is a problem with frameworks that insist on properties (i.e. Data Binding). Also, I just got to 5 as arity goes. The day I need 6 items, I’ll add another one. It is boilerplate code (that I’d still like not to write).


    The Equals method is a bit convoluted:

        internal static class Utils {

    public static void CheckNull<T>(T t) {

    if (t == null)
    throw new ArgumentNullException();
    }
    }

           public override bool Equals(object right) {

    Utils.CheckNull(right);

    if (object.ReferenceEquals(this, right))
    return true;

    if (this.GetType() != right.GetType())
    return false;

    var rightT = right as Tuple<T1, T2, T3>;

    return base.Equals(rightT) && F.DSEquals(this.Item3, rightT.Item3);
    }


    I always get complaints when I show Equals methods that throw if null is passed in, but I stand by my logic, that the presence of null for these categories of ‘structurally equal’ classes is symptom of an error and I want to be notified. Returning false doesn’t do that.

            internal static bool DSEquals<T>(T left, T right) {

    if (left == null && right == null)
    return true;

    if (left == null && right != null)
    return false;

    var len = left as IEnumerable;
    var ren = right as IEnumerable;

    if (len == null && ren == null)
    return left.Equals(right);

    if (len == null && ren != null)
    return false;

    if (len != null && ren == null)
    return false;

    return SequenceEqual(len, ren);
    }


    DSEquals check the content of the Tuple and forward to SequenceEqual in case one slot of the Tuple contains an IEnumerable.

            internal static bool SequenceEqual(IEnumerable en1, IEnumerable en2) {

    var enumerator = en2.GetEnumerator();
    foreach (var o in en1) {

    if (!enumerator.MoveNext())
    return false;

    if (!DSEquals(o, enumerator.Current))
    return false;
    }


    SequenceEqual checks that the number of items in the enumerator is the same and recursively calls DSEqual to check structural equality for items at the same index in the two enumerators.


    GetHashCode is trivial (and maybe trivially wrong, one of these days I’ll learn everything about GetHashCode() ).

            public override int GetHashCode() {

    return base.GetHashCode() | Item3.GetHashCode();
    }


    The equality operators are equally simple.

            public static bool operator ==(Tuple<T1, T2, T3> t1, Tuple<T1, T2, T3> t2) {

    Utils.CheckNull(t1);
    Utils.CheckNull(t2);

    return t1.Equals(t2);
    }
    public static bool operator !=(Tuple<T1, T2, T3> t1, Tuple<T1, T2, T3> t2) {

    return !(t1 == t2);
    }


    And ToString() prints my favorite Tuple format.

            public override string ToString() {

    return string.Format(“{0},{1}”, base.ToString(), Item3.ToString());
    }


    I’m sure you can find plenty of issues in this code. As always, it is not ‘production ready’, it is more ‘Luca having fun doing it’. In any case, there are some testcases in the solution to check the extent of my testing.


    In the next post we’ll look at Records.

    Functional.zip

    A C# library to write functional code – Part I – Background

    Other posts in the series:


  • Part I – Background
  • Part II – Tuples
  • Part III – Records

  • Part IV – Type Unions

  • Part V – The Match operator

  • In December (slow time in msft) I decided to understand what functional programming is all about. When I say ‘understanding’ I don’t mean just paying lip service to the main concepts by knowingly mentioning them in casual conversations (i.e. “look at this memoization, man!” or “this lambda function is so hot!”. I can already do that. I intellectually know what the thing is.


    I wanted to *really* understand it. For me that means writing plenty of code. I had a medium size application in my mind that I’ve been wanting to write for quite some time (stock price, dividends, splits downloading and various return calculations), so I went ahead and wrote it. I also wanted to use C#. It would have been easier in F#, but I work on the C# team and love using our own product.


    My early attempts were unpleasing. I would fall back to my OO background and my functional code slowly reverted to OO code. My way of thinking about it, even if starting with the best intentions, would go back to: what are the objects, what are their responsibilities and such.


    I needed to force myself somehow; kind of overcompensate on the other side. I hit on the idea of pragmatically defining functional programming and try to limit myself to the subset of language constructs inside my definition. As a way to define it, I used Chapter 3 of “Expert F#“. I know, I know, I could have read 1,000s of academic papers and come up with a meta-analysis of all of them that formally defines what ‘functional programming’ really is. But life is too short. I trusted Don.


    The problem is, several of the language constructs in my small definition of functional programming don’t exist in C#. So I went ahead and created them. I built a little library to represent them and forced myself to write code using just this library. It worked.


    In this series of posts I will describe what’s inside this library. I want to emphasize that I built it for educational purpose only, not for performance or production code. Caveat emptor.


    My plan is to cover the following:



    1. Tuples
    2. Records
    3. Type Unions
    4. Match

    Let’s see if I can find the time to actually write these posts :-)