About Jolt.NET Libraries

Inspired by the Boost C++ libraries, Jolt.NET aims to complement the .NET Base Class Library (BCL) with algorithms, data structures, and general productivity tools. It is the hope of the authors that the features of Jolt.NET will one day be part of, or represented in the BCL and the .NET Framework.

Jolt.NET Feature Triage

You may have noticed through the feature RSS feed that I've been busy opening/closing items and shuffling things around.  I've postponed work on some documentation tasks that didn't make much sense for a project of one developer.  Also, I decided that I won't implement the Tuple library as the upcoming release of the .NET Framework 4.0 will contain an implementation similar to what I had planned.  .NET 4.0 is currently available in beta/CTP for download.

The triage slashed the number of items that I wanted to complete for Jolt.NET 0.3, and that prompted me to think about including another feature in the release.  When I first started work on Jolt.NET, I wanted to include a test facility to make assertions on XML data structures.  After releasing Jolt.NET 0.1, I decided not to implement this feature as it would be available in NUnit 3.0.  However, I think this decision was premature as not all testing frameworks will support this feature.

So over the next few days, I will be drafting an implementation and feature set for extending a test framework to support assertions on XML data.  I suspect that I will need some adapter classes to expose the feature in various test frameworks, and at this time, I'm not sure how many of these frameworks to support.

Static Idempotent Functors

The task of replacing inline anonymous methods with a generic functor from the Jolt.Functional library brought forth some interesting issues, all of which have been addressed as of revision #19483.  The main topic that I will discuss in this post deals with the implementation and usage of the Functor.Idempotency and Functor.TrueForAll generic factory methods.

The TrueForAll factory method creates a delegate that returns true for any input, and thus it is natural to implement this method in terms of the Functor.Idempotency method since TrueForAll is a Boolean idempotent predicate.  My main use of TrueForAll in Jolt.NET was in testing the serialization of finite automata to GraphML.  If you’ve used this library, you may recall that there are limitations when serializing of a TransitionPredicate.  Specifically, the predicate must refer to a static method.  So, is it possible to implement a generic idempotent method that is static?  Let’s take a look at the function signature that we need to satisfy, along with the current implementation.

using System;

// One-arg idempotent method; overloads exist for zero through four args.
static Func<T, TResult> Idempotency<T, TResult>(TResult constant)
{
return arg => constant;
}

In this example, the method that ultimately implements the inline expression can not be static since it uses a variable that is not local to the expression (see “Anonymous Methods and Jolt Functors: Behind the Scenes” for more information).  Consequently, the resulting delegate refers to a non-static method.  If the hidden class that implements the expression were static, then we could only ever have one idempotent delegate per unique specialization. per app-domain, as demonstrated in the following example.


using System;

static class IdemptotencyWrapper<TConstant>
{
static TConstant constant;
static TConstant Idempotency<T>(T arg)
{
return constant;
}
}

static Func<T, TResult> Idempotency<T, TResult>(TResult constant)
{
IdempotencyWrapper<TResult>.constant = constant;
return IdempotencyWrapper<TResult>.Idempotency<T>;
}

void UseFunctors()
{
Func<int, bool> falseForAll = Idempotency<int>(false);
Func<int, bool> trueForAll = Idempotency<int>(true); // Oops! Changed the behavior of falseForAll.
}

Another novel attempt at solving this problem is to use an expression tree to force the user-provided constant to be local to the expression.

using System;

static Func<T, TResult> Idempotency<T, TResult>(TResult constant)
{
Expression<Func<T, TResult>> expression = Expression.Lambda(
Expression.Constant(constant, typeof(TResult)),
new[] { Expression.Parameter(typeof(T), arg) });
return expression.Compile();
}

This solution looks good, has some performance deficiencies we can live with, and may even provide the static method that we need.  However, the method that is produced is compiled and created at runtime.  In other words, it doesn’t exist in the assembly and thus not feasible for textual serialization.

I’m also uncertain on whether this method is truly static.  The MethodInfo object representing the delegate’s method states that IsStatic is true, but the delegate’s Target property gives a non-null value.  Very strange.

If we want to persist the method that is represented by the expression, we can utilize the Reflection.Emit API and create an assembly that contains the desired method.  The performance deficiency is even greater with this solution and is overkill for the general usage of the Idempotency method.  While the serialization problem is addressed, the deserialization problem is not; this generated assembly is not distributed with the library and thus the referenced methods may not exist in deserialization environment.

In conclusion, I could not conceive of a way to modify the Idempotency method implementation to meet my criteria, so I decided to keep it as is.  The implementations of TrueForAll and FalseForAll were modified to return constants local to the expressions, thus making the resulting delegate refer to a static method.

Adaptors For Delegate Types

Recently, I’ve been working on creating adaptors for delegates of equivalent types.  Given the generic types Predicate<T> and EventHandler<TEventArgs>, I would like to create a function that transforms instances of these types into Func<T, bool> and Action<object, TEventArgs> respectively, and vice-versa.  This is a fairly straight-forward task to accomplish, but implementing a correct solution depends on what your expectations are with regards to what the resulting delegate references.

My goal is to create a new adaptor delegate that refers to the same method that is referred to by the adaptee.  When implementing the adaptor function for the Predicate<T>/Func<T, bool> case, I implemented the incorrect solution twice.  On the second attempt, I also implemented the incorrect test code, which was very negligent on my part.  It was only until other unrelated tests start failing, that I noticed my error: I had changed the semantics of the implementation and consequently the expectations of the unit tests.

Let’s look at three ways to implement a function that creates an adaptor delegate for Predicate<T>.

Option 1 : Lambda Expressions


using System;

Func<T, bool> CreateFunc<T>(Predicate<T> predicate)
{
return arg => predicate(arg);
}

This solution uses a lambda expression to create a new delegate that forwards its call to the adaptee.  The forwarding operation is implemented by the compiler as a new method on a compiler-generated type.  Clearly, this is does not achieve my goal since the method referred to by the adaptor is different from that referred to by the adaptee.

Option 2 : Delegate Constructor 

using System;

Func<T, bool> CreateFunc<T>(Predicate<T> predicate)
{
return new Func<T, bool>(predicate);
}

This solution initializes an instance of the adaptor delegate with the adaptee instance.  It looks like a copy constructor has been invoked, as the constructor accepts anything that implements the delegate’s signature.  However, don’t be deceived by the copy-constructor-like syntax of this operation.  The constructor has in fact added the adaptee to the adaptor’s invocation list.  Consequently, the method referred to by the adaptor is the Invoke() method of the adaptee.  If the constructor parameter were a method, then the resulting adaptor delegate would refer directly to the given method.

Option 3 : Delegate Factory Method

using System;

Func<T, bool> CreateFunc<T>(Predicate<T> predicate)
{
return Delegate.CreateDelegate(typeof(Func<T, bool>), predicate.Target, predicate.Method) as Func<T, bool>;
}

This solution utilizes a bit of reflection and a static factory method on the delegate class to construct the adaptor.  Notice that the factory method accepts a MethodInfo object, denoting the method that the resulting delegate will directly invoke.  Alas, we have arrived at the solution that implements my expectations.  Even though the adaptor and adaptee delegates are of different types, they both internally refer to the same method.

There is one gotcha that you should be aware of – this may be a bug with in the .NET Framework, or misstated information in the documentation.  If you refer to the documentation on the Delegate.CreateDelegate(Type, MethodInfo) method, you will notice that the method supports both static and instance methods for binding (.NET 2.0 and onwards).  However, disassembling the method in question shows that this is not the case; this overload only functions with static methods, always passing a null reference as the target object of the new delegate.  In my example above, I use another overload that accepts the target parameter to assure that both static and instance methods are adaptable.

Jolt.NET Functor Composition

I recently completed the implementation of the generic Compose class, allowing a caller to build composite functors with up to seven parameters.  In this post, I will discuss the implementation and a minor coding nuisance that I encountered while writing the code.  But first, here is a quick recap the features that were committed since my last post.

  • Jolt.Functional functor creation and manipulation library (see this post, and the docs)
  • Ability to override return type in Jolt.Testing.ProxyTypeBuilder (see this post, and the docs)

Compose Implementation

The Compose class is implemented as a collection of generic static functions: First, Second, Third and Fourth.  Each of these functions binds the execution of a delegate to an argument of another delegate, the position of the argument being denoted by the function’s name. A composite delegate is represented as a new delegate, and its generic implementation takes care of binding arguments and calling the composed delegates at the right time.  Functor composition is very similar to argument binding, except that the bound arguments are now delegates instead of constant values.

The rules and supported scenarios for creating a composite are straightforward:

  • You can bind any System.Func functor F to an argument A of any System.Action or System.Func delegate so long as the return type of F matches the type of A.
  • Only one functor can be bound per Compose method call.
  • Bound functors are executed when the resulting composite is executed, in LIFO order.
    • E.g. Given a binary functor F, nullary functors G and H, and the composite c = Compose.First(Compose.First(F, G), H), executing c() results in the execution of H first, followed by G and F.
  • Creating a composite yielding more than four arguments results in a Jolt.Functional.Action or Jolt.Functional.Func delegate, each of which support five through seven arguments.

When writing the methods of Compose, I was primarily concerned with enforcing the rules from the first bulleted item above at compile-time.  Doing so would ensure that the creation of the composite is as fast as possible since the code would not need to perform checks for possible user errors.  Unfortunately, taking this approach meant that I would need to declare every possible permutation of binding a 1-4 argument delegate with a 0-4 argument functor.  There are a total of 100 of such combinations, and the only difference between any two given functions is generally the number of delegate arguments and the position at which the binding occurs.

To the best of my knowledge, there is no way to use generics to reduce the number of functions that are needed to implement all of the desired combinations.  C# does not allow a generic parameter to be constrained to a System.Delegate type, and if it were possible, there is still no facility to constrain a delegate to one with a given number of arguments.  For this situation, a C++-like variadic template argument or typelist feature is very desirable as it will eliminate the method overloads enabling composition of functors with varying arguments.  To illustrate, one could reduce the number of First method overloads from 40 to 8 using the following variadic generic argument pseudocode.

public static class Compose
{
public Func<params Args, TResult>
First<T, TResult, params Args>(Func<T, TResult> function, Func<params Args, T> innerFunction);
public Func<params Args, TResult>
First<T1, T2, TResult, params Args>(Func<T1, T2, TResult> function, Func<params Args, T1> innerFunction);
public Func<params Args, TResult>
First<T1, T2, T3, TResult, params Args>(Func<T1, T2, T3, TResult> function, Func<params Args, T1> innerFunction);
public Func<params Args, TResult>
First<T1, T2, T3, T4, TResult, params Args>(Func<T1, T2, T3, T4, TResult> function, Func<params Args, T1> innerFunction);

public Action<params Args>
First<T, params Args>(Action<T> function, Func<params Args, T> innerFunction);
public Action<params Args>
First<T1, T2, params Args>(Action<T1, T2> function, Func<params Args, T1> innerFunction);
public Action<params Args>
First<T1, T2, T3, params Args>(Action<T1, T2, T3> function, Func<params Args, T1> innerFunction);
public Action<params Args>
First<T1, T2, T3, T4, params Args>(Action<T1, T2, T3, T4> function, Func<params Args, T1> innerFunction);
}

An alternate implementation technique is to utilize reflection to compose abstract System.Delegate instances.  As mentioned earlier, this solution requires additional code to guard against user errors.  It would also rely heavily on reflection to determine the type of and create an instance of the resulting delegate.  The implementation will not perform as well as the many-overloads solution, but has the benefit of producing far less code to maintain.  It also removes the restriction of delegate types that are usable with the library (System.Action and System.Func), even though this isn’t a bad restriction.

In the end, I chose to avoid the reflection-based approach favoring runtime speed and a strongly-typed interface over smaller code quantity.  The implementations of the Compose methods and their tests are trivial, and if I had to write such a class again, I would likely implement a code generator to emit all of the desired permutations.  Implementing the code generator may not be such a trivial task, but it will likely take far less time than copying and tweaking code, and making sure that the XML doc comments for the new code is correctly specified.

Finally, I should note that the reflection-based approach has the merit of enabling composition/binding support for abstract System.Delegate instances.  We can utilize a method similar to the following to convert a System.Delegate to its equivalent System.Action or System.Func counterpart.  The resulting delegate may then be used with the Jolt.Functional classes.


public static class Convert
{
public static Action ToAction(Delegate function)
{
// TODO: validate input and cast.
return Delegate.CreateDelegate(typeof(Action), function.Method) as Action;
}
}