Tuesday, April 2, 2013

Sasa's Core Interfaces

This is the eleventh post in my ongoing series covering the abstractions in Sasa. Previous posts:

I covered some of Sasa's core interfaces previously, but I shall provide a more thorough treatment here.

Sasa.IValue<T>

Fundamentally, programs manipulate values. These values can often be classified into various categories depending on how they can be manipulated or computed. At the most basic level, we have a simple value represented by Sasa.IValue<T>. IValue<T> provides only a single property to access the encapsulated value:

IValue<int> x = new Immutable<int>(3);
Console.WriteLine(x.Value);
// output:
// 3

This demonstrates the use of a simple immutable value class, but the Value property need not be so simple. It can even throw exceptions in some cases. For instance, as covered in a previous article Sasa.Result<T>.Value throws InvalidOperationException if the result was an error instead of a value.

Sasa.IRef<T>.Value

Sasa.IRef<T>.Value extends the read-only Sasa.IValue<T> with a setter for the Sasa.IRef<T>.Value property:

IRef<int> x = new Ref<int>(3);
x.Value = 999;
Console.WriteLine(x.Value);
// output:
// 999

Sasa.IVolatile<T>.TryGetValue

Some values may or may not be present, and it's often necessary to check for the presence of a legitimate value and to obtain that value in a single step. Enter IVolatile<T>, which provides a standard interface for the common TryGetValue pattern:

IVolatile<int> withValue = new Option<int>(3);
int value;
if (withValue.TryGetValue(out value)) Console.WriteLine(value);

IVolatile<int> noValue = Option<int>.None;
if (noValue.TryGetValue(out value)) Console.WriteLine(value);

// output:
// 3

Sasa.IResolvable<T>.HasValue

Similar to IVolatile<T>, IResolvable<T> standardizes an interface for values that may or may not be present by exporting a HasValue property:

IResolvable<int> withValue = new Option<int>(3);
if (withValue.HasValue) Console.WriteLine(withValue.Value);

IResolvable<int> noValue = Option<int>.None;
if (noValue.HasValue) Console.WriteLine(noValue.Value);

// output:
// 3

Sasa.IOptional<T>

Sasa.IOptional<T> is an interface that implements IVolatile<T>, IResolvable<T>, and IValue<T>. It is implemented by many of the abstractions in Sasa that encapsulate values, like Sasa.Option<T> and Sasa.Result<T>.

Sasa.IResult<T>

Sasa.IResult<T> describes values that resolve either to a value or an error. It's an abstraction that implements IOptional<T>, IVolatile<T>, IResolvable<T>, and IValue<T>, and also exports an Error property:

IResult<int> withValue = new Result<int>(3);
if (withValue.HasValue) Console.WriteLine(withValue.Value);

IResult<int> noValue = Result.Fail<int>(new ArgumentException());
if (noValue.HasValue)
    Console.WriteLine(noValue.Value);
else
    Console.WriteLine("Error: {0}", noValue.Error.Message);

// output:
// 3
// Error: ArgumentException ...

This interface is implemented by Sasa.Result<T> and a few other abstractions in Sasa. Sasa.Result also implements the LINQ query pattern on IResult<T> instances.

No comments: