Language: EN

csharp-language-ext

Functional Programming in C# with the LanguageExt library

LanguageExt is a functional language extension library for C#. It was created by Paul Louth and aims to facilitate working with functional features in C#, such as functional programming, immutability.

LanguageExt is based on best practices in functional programming and provides a wide range of data structures and functions to help developers write cleaner, more concise, and safer code.

LanguageExt provides a wide range of functional features for C#, including:

  • Immutable data structures, such as lists and maps.
  • Higher-order functions, such as map and fold.
  • Asynchronous programming with support for cancellation and exceptions.
  • Option and result types to avoid runtime exceptions.
  • A concurrency system based on agents and channels.

This library is not small. On the contrary, it is a huge library, which provides a large number of tools that represent a significant change in the way C# is used.

However, it is not necessary to use all the tools all the time. LanguageExt is presented as a collection of utilities that are beneficial to use on some occasions.

On the other hand, many of the features offered by LanguageExt have been gradually incorporated into .NET versions, which continue their own evolution towards more functional paradigms.

Personally, I also see this library as a “testing ground” for new possibilities and trends in software development, as well as providing certain practical utilities that do have an immediate use.

How to use Language-ext

We can easily add the library to a .NET project, through the corresponding Nuget package.

Install-Package LanguageExt.Core

Here are some examples of using Language-ext extracted from the library’s documentation

Null

We can easily handle Null objects thanks to Option<T>

var optional = Some(123);

int x = optional
        .Some( v  => v * 2 )
        .None( () => 0 );

int x = optional.IfNone(10);  

Matching

Using Option<T> along with matching.

Option<int> two = Some(2);
Option<int> four = Some(4);
Option<int> six = Some(6);
Option<int> none = None;

int r = match( from x in two
                from y in four
                from z in six
                select x + y + z,
                Some: v => v * 2,
                None: () => 0 );     // r == 24

Out Parameters

Avoid using Out parameters through Option<T>

int res = parseInt("123").IfNone(0);

int res = parseInt("123").Match(
                Some: x => x * 2,
                None: () => 0
            );

Unit

Unit data type to avoid using void to indicate absence of type.

public static Func<string, Unit> GetConsoleWrite() => fun<string>(Console.Write);
public static Func<string, Task<Unit>> GetConsoleWriteAsync() => (string v) => Console.Out.WriteAsync(v).ToUnit();

public static Unit WriteToConsole(string v) => fun(() => Console.Write(v))();
public static Task<Unit> WriteToConsoleAsync(string v) => Console.Out.WriteAsync(v).ToUnit(); 

Collections

It also offers immutable collections, such as lists and maps

var test = List(1, 2, 3, 4, 5);
var list = Range(500,1000);

var res = List(1, 2, 3, 4, 5)
            .Map(x => x * 10)
            .Filter(x => x > 20)
            .Fold(0, (x, s) => s + x);

Or, for example, immutable dictionaries

var dict = Map<string,int>();

var people = Map((1, "Rod"),
                (2, "Jane"),
                (3, "Freddy"));

Option<string> result = find(people, 1);

var res = match( find(people, 100),
                    Some: v  => "Hello " + v,
                    None: () => "failed" );

Functions

Definition of functions under a more functional paradigm

public int Sum(IEnumerable<int> list) => match( list,
            ()      => 0,
            (x, xs) => x + Sum(xs)
);

These are just examples of some of the features. But the library offers many, many (many!) Check out the documentation because it’s really interesting, even if it’s just as a source of inspiration and ideas.

Language-ext is Open Source, and all the code and documentation is available in the project’s repository at https://github.com/louthy/language-ext