Introducing Succinc<T> – functional additions to C#

SuccincT logoTo certain extent, the title of this post is a little dishonest: it’s not really the first time I’ve introduced Succinc<T> on this blog. I first mentioned it over two years ago. To explain the title therefore, some history is required.

During early 2013, I was indulging myself in a “thought experiment” language: Lapsang. One such thought experiment was around the idea of whether a language could sensibly support the concept of not throwing exceptions for petty, unexceptional, reasons.

An example I used of such an exception was those thrown by the .NET framework Parse methods. The framework offers two options: Parse and TryParse. The first handles not being able to parse the string by throwing exceptions. The latter (as its name suggests) does two things and returns two results. The method returns a boolean to indicate if the string could be parsed and it returns the value – if it could be parsed – via an out parameter. Both therefore have problems. In the first case, lots of boilerplate try/catch code has to be written to handle non-parsable strings. In the latter case, the single responsibility pattern is broken through the use of the out parameter “code smell”. What I wanted was a method that could return a single result that encapsulated the success or not and the value if successful, with that result being invalid if the parse was unsuccessful. You can read the full details of my thinking at the time in SuccincT – A .NET framework to solve unexceptional exceptions & out parameter annoyances as well as Some thoughts on expanding SuccincT to provide richer interface contracts and auto-generated data classes.

As part of exploring ideas for Lapsang, it was suggested to me that I should learn about F# as its functional approach to coding problems had some nice ideas. So I put Succinc<T> to one side and started learning about functional languages.

The result of this was that I learned about option types, which were exactly what I was trying to achieve in the first place. On and off over the last couple of years, Succinc<T> has been totally rewritten and expanded way beyond my original idea. As a result, it now warrants a complete re-introduction. Thus this post.

Option<T>
As this type was born out of the original ideas for Succinc<T>, it seems the obvious place to start. An optional type either has some value, or it has none. The library has a set of extension methods added to the string type for parsing for numeric, boolean and enum values. Each returns an option of that type. For example:

returns an Option that contains the value 123. Whereas:

returns an Option that contains None.

To read more about options, please see the Option page on the Succinc<T> wiki.

Discriminated Unions
The option type is an example of a discriminated union. This is a type that contain one of a number of types. In this case either some value or None. Succinct also supports mere generic option types though of between two and four types. For example, a union of int and string can contain either an int or a string. The union can be tested to determine what type it contains and the value retrieved in a type-safe fashion.

To read more about discriminated unions, see the Union<T1,t2>, Union<T1,T2,T3> and Union<T1,T2,T3,T4> pages on the Succinc<T> wiki.

Pattern matching
Whilst options and other discriminated unions are powerful constructs in their own right, their real power comes into play when combined with pattern matching. For those unfamiliar with this functional language construct, it can be though of as a syntactically lightweight switch statement on steroids. Firstly, unlike switch, each case in a pattern match need not be a constant. It can be an expression, including the invocation of a lambda. Secondly, unlike switch, which simply selects a code block to run, the result of a pattern match can be a value, again including that from invoking a lambda. Effectively it’s an expression in itself. This leads to some very concise (succinct even, if you’ll excuse the pun) value evaluation code, as shown in the following example for a number guessing game:

Succinc<T>’s pattern matching isn’t just restricted to unions though. It can be applied to a special string & string union, ValueOrError, tuples and any other type. See the pattern matching guide on the wiki for more details.

Partial Function Applications
Many functional languages support partial function applications. This is a long term to describe something really quite simple: a function that takes more than one parameter is called with just one parameter, which returns a new function that now only needs the remaining parameters. This can be more readily explained with a small piece of F# code:

double is defined as a version of multiply with the first parameter, 2, already supplied. It’s then invoked like a normal function and it supplies the 2, plus its own parameter to multiply and the result is returned.

Using Succinc<T>, a similar thing can be achieved with C#:

C#’s type inference is nowhere near as powerful or advanced as F#’s, so the syntax isn’t as compact, but it’s fairly close.

F# is limited to partially applying parameters to the front of the list. However, there is a use case for wanting to apply them to the end: dealing with optional boolean parameters that plague the C# (and .NET framework) worlds. By way of an example, consider the Directory.Delete() method. Call Directory.Delete(someDir) or Directory.Delete(SomeDir, false) and it will delete SomeDir if empty. Change it to Directory.Delete(SomeDir, true) and a monster delete-everything-in-its-path method is unleashed. Being a core feature of the framework, you probably knew this. You only know it though through reading the docs though; not through looking at the method name and parameter.

By using tail-wise partial application of the last parameter, new – meaningful – names can be assigned to partially applied functions:

To read more about using Succinc<T>’s partial function applications, see the wiki page.

Getting hold of Succinc<T>
If the above has tempted you to try out Succinc<T>, you can find it on NuGet, or search in the NuGet package manager in Visual Studio.