Simple railway style

You shouldn’t use exceptions for normal business logic handling. It’s better to have your methods return early with either the successful result or some failure detail. Expected in this case means implies that it’s the result of a business check: the data you’re processing isn’t in the right form, for example. Doing so means you litter your code with conditional boilerplate that checks if (!success) return SomeFailureDetail or similar.

Railway oriented programming style hides this boilerplate code by using a standardised return wrapper and a set of related methods that apply the boilerplate conditional. It’s also an interesting application of monads in a functional style, but it’s not critical to understand that to use it.

Consider a method that appends -foo to an input string.

Imagine that it’s possible for this to fail – maybe it doesn’t like some input strings for example. Rather than throw an exception it should return some information that describes the failure, like:

If we want to chain a set of these operations together however we need to intersperse the steps that check for failure each time, which obfuscates the flow:

First, let’s create a class called Either, that we’ll use in place of the tuple cotaining either a failure or result.

Then add some extension methods that let us chain these things together. Fans of functional programming will recognise Bind but will realise that it’s missing support for a few operations that’d make it monadic:

Then if we modify GetFoo to use the Either:

We can demonstrate a chain of operations where every operation is called successfully, and a chain of operations that fails on the second op, meaning the final operation isn’t executed:

And all with fairly minimal boilerplate to get in the way. We could rename Lift as Wrap and Bind as Do for extra clarity.