Why records must be sealed

Posted on Updated on

When most people (and I include myself in this) start to learn a functional programming language like F#, they are immediately surprised by the lack of inheritance. It’s such a mainstay of our daily programming that we’re initially nonplussed when it’s taken away… In this post I want to talk about the problems introduced by mixing inheritance with the notion of structural equality, and thus why any language which implements the concept of a record type must also prohibit inheritance of such a type.

For the record (ahem), a record is a type where one simply declares the shape of the class (i.e. the names and types of the public members), and then the constructor, equality and hashcode methods are generated for you by the compiler. An example in F# might be this:

type PersonName = { firstName : string; surname : string }

which is roughly equivalent to the following C#:

public sealed class PersonName : IEquatable<PersonName >
{
	public string FirstName { get; }
	public string Surname { get; }

	public PersonName (string firstName, string surname)
	{
		FirstName = firstName;
		Surname = surname;
	}

	public bool Equals(PersonName other) =>
		other != null &&
		other.FirstName == this.FirstName &&
		other.Surname == this.Surname;
		
	public override bool Equals(object other) => 
		this.Equals(other as PersonName );
		
	public override int GetHashCode() =>
		FirstName.GetHashCode() ^ Surname.GetHashCode();
}

So a record is just a specific kind of class, why would allowing inheritance of this class cause a problem? Let’s imagine a simple object to model a Cartesian point:

public class Point : IEquatable<Point>
{
	public int X { get; }
	public int Y { get; }

	public Point(int x, int y)
	{
		X = x;
		Y = y;
	}

	public bool Equals(Point other) =>
		other != null &&
		other.X == this.X &&
		other.Y == this.Y;
		
	public override bool Equals(object other) => 
		this.Equals(other as Point);
		
	public override int GetHashCode() =>
		X.GetHashCode() ^ Y.GetHashCode();
}

This looks good: it implements the IEquatable<> interface as well as overriding object.Equals(), and we can show that two points with the same x and y values are considered equal, as one would expect:

	var a = new Point(1, 2);
	var b = new Point(1, 2);
	
	Console.WriteLine(a.Equals(b)); // -> True

However, the point class is not marked as sealed, meaning that (anyone) is free to derive this class and potentially break the concept of equality for our Point class. Suppose someone consumes our class library and introduces a new type: Point3D.

public class Point3D : Point, IEquatable<Point3D>
{
	public int Z { get; }

	public Point3D(int x, int y, int z) : base(x, y)
	{
		Z = z;
	}

	public bool Equals(Point3D other) =>
		other != null &&
		other.X == this.X &&
		other.Y == this.Y &&
		other.Z == this.Z;

	public override bool Equals(object other) =>
		this.Equals(other as Point);

	public override int GetHashCode() =>
		X.GetHashCode() ^ Y.GetHashCode() ^ Z.GetHashCode();
}

Again, all looks good:

	var a = new Point3D(4, 5, 6);
	var b = new Point3D(4, 5, 6);

	Console.WriteLine(a.Equals(b)); // -> True

But hang on… if we stop and think about the type hierarchy that we’ve created, it’s already starting to look a bit weird. A Point3D is IEquatable<Point3D>, as you’d expect, but because it inherits from Point it also implements IEquatable<Point>. That means that you can compare a Point3D and a Point for equality, which doesn’t really make sense, but sure enough:

void Main()
{
	var a = new Point(4, 5);
	var b = new Point3D(4, 5, 6);

	Console.WriteLine(a.Equals(b)); // -> True
}

This isn’t right any more. We’ve compared two objects of different types but they’ve returned Equals() -> True. But, here’s the thing about polymorphism: when the Point.Equals(Point) method is executed, we don’t know whether the object that was passed in is actually a Point or whether it’s an instance of some other class that derives from Point, so we can’t actually calculate equality. The only real solution to this (beyond a bit of a hack in the equality method to call GetType on both objects) is to make sure that the class Point can have no inheritors.

In an object oriented language like C#, the rule might be expressed as “any type that implements one or more equality methods must also be sealed”.

Roslyn analyzers

Posted on Updated on

I’ve finally decided to get in on that sweet, sweet Roslyn action and write myself an analyzer (please forgive the American spelling–since I’m programming against a series of types defined in American I’ve decided to use their spelling).

You’ll probably know I’m a big fan of functional programming and I’m trying to write my C# in a more functional style; I’ve found that you can get many of the benefits of functional programming even though you’re not writing in a functional language.
As it turns out, sometimes removing certain features from your programming language (or, at least, disallowing certain actions) can actually improve your code. An easy example of this is the goto statement; despite the fact that the C# language supports goto nobody uses it because it’s widely regarded as a harmful thing to do.

Read the rest of this entry »

Some functional types in C#

Posted on Updated on

Update: I now have a project on GitHub containing this code at https://github.com/Richiban/Richiban.Func Check this repository for up to date code.

Continuing with my long-running train of thought in bringing some functional programming concepts to my C# projects, I have implemented a type called Optional, roughly equivalent to `Option` from F# or `Maybe a` from Haskell. If you’re not familiar with these concepts, then imagine Nullable from .NET, but applicable to all types (not just value types). The whole idea is that, rather than using a null reference of T to represent a missing value you use a new type–Optional–that can exist in one of two states: it either contains a value of T or does not.

This is a very important difference that I will explain over the course of this post. First, let’s look at the type definition itself. It’s quite long, so feel free to skim-read it at this point and refer back to it at later points in the post.

Read the rest of this entry »

The dangers of primitive obsession

Posted on Updated on

Primitive obsession is, like many facets of modern programming, something that has been written about many times before (e.g. http://sourcemaking.com/refactoring/primitive-obsession, http://blog.thecodewhisperer.com/2013/03/04/primitive-obsession-obsession/), yet still we see its ensnaring of unwary programmers.

Read the rest of this entry »

C# needs to allow us to write code in a more functional, immutable style

Posted on Updated on

Since C# 6.0 is now feature-locked (and I can’t wait) it’s time to start talking about something that might be in the next version, assumedly called C# 7.0.

The big feature for me would be to get C# to help us write immutable code. That means they need to make it easy to write immutable classes (see my last post on Record types) and immutable local variables too.

I propose the following syntax:

Read the rest of this entry »

My proposed syntax for record types in C#

Posted on Updated on

With the impending release of C# 6.0 and all its new features, I have been thinking about what might come in the next version of C# (v7.0, I’m guessing). There has been talk in the Roslyn forums about things such as pattern matching and record types (the latter being especially important since the primary constructors feature was dropped from C# 6.0).

Below is a quick sketch of how I think record classes should work in C#. You can probably tell that I spend a lot of time programming functionally, because I’ve included a number of syntax features here to make immutability a very easy option.

Read the rest of this entry »

London photowalk

Posted on Updated on

Last week I went on a photowalk with friends. The idea is that people with a shared interest in photography meet up and walk along a pre-prepared path, taking pictures as they go. The walk started at the Hays Galleria near London Bridge and we continued through the Inner London Pool starting on the South side of the river and travelling over to the North side and back again.

Along the way we took in some of London’s finest landmarks through the back streets finding views of London Bridge, the Shard, the Tower of London, Monument and more. This one was part of the Kelby Worldwide Walks and there was a competition to go with it.

I have included a gallery of the shots I took (and decided to keep), and the photo I entered into the competition too.