CallStream Part 2 : C# Binding

In the second part of CallStream series, I shall try and contribute with my own C# implementation of the CallStream .

First thing first. I do realize that F# is much more natural choice for the kind-of-a programming CallStream is all about : functional and all that. But in spring 2010, C# is unavoidable. Betrand Le Roy (BLR) has contributed first and actually produced a critical C# idiom that allowed me to work furher on the C# binding of the CallStream.
[sourcecode language=”csharp”] // (c) 2010 by Bertrand Le Roy
public delegate CallStream CallStream (Action<object> action, object options = null);
[/sourcecode] As BLR says : “..Tricky, but that actually works, a delegate can return its own type…” . I doubt that 99.9% of C# population knew this is possible. Me including. I have to admit that last two years, I spent in (very) intensive JavaScript-ing. Inevitably my C# become a bit rusty, after I left it “temporarily” sometimes way back in 2005. But now I want to provide some input to CallStream C# implementations that (it seems) will inevitably come in larger numbers.

Since release of C#3.0 , it is possible to do a lot of functional programming in C#, and that is a good thing. But, in C#, there is an sizeable “dark matter” accumulation. Some say, C# is by now, far from simple and elegant programming language. Also, dynamic and functional .NET languages like Iron Python and F# have started to appear. And F# now has a prefix Visual, and we all know what that means 😉 The point I am making is that C# is not the best programming language in the world ever, but it is an official .NET language, and in widespread use. And CallStream concept can and should be quite nicely implemented in C#. As BLR has already shown, and I will try and formalize in this post.

Implementation

My current official shape of CallStream is presented in the form of JavaScript source.
I have decided to try and present C# form of CallStream and CallStreamBridge. But what about the CallStreamConstructor? I think that the JavaScript form of CallStream, reveals completely the spirit of that language. As a such it is not trivial to implement in C#, which is inherently NOT an functional language, and certainly not an prototypical language. Still there are at least several ways to do this, more or less successfully. I think it is best NOT to dictate a C# binding of that part of CallStream. There is no generic “best” way to do this. Different kinds of C# components and programs will require different C# specific implementations of initialization (aka contruction) of the CallStream encapsulation. So, I decided it is best to declare CallStreamBridge , C# binding : ” an excersize for the reader” 😉

Now, back to the core CallStream parts. Obviously BLR has already done a key contribution and I will use it. But with a twist: I will make it a bit more generic.
[sourcecode language=”csharp” light=”false”] /// <summary>
/// Encapsulates an method that takes any number of parameters of any type
/// and returns void
/// </summary>
public delegate void TheFunction(params object[] paramz);

/// <summary>
/// A signature of the method that is a bridge between CallStream
/// and some state implementation that CallStream is "hiding" from the callers
/// This method is used for each call in the CallStream.
/// </summary>
/// <param name="function">the user provided function in the single call</param>
/// <param name="options">optional arguments for the function provided </param>
public delegate void CallStreamBridge<T>(T function, params object[] options);

/// <summary>
/// Encapsulate a call stream as something that takes an
/// Action of type T and an optional params object array
/// And that returns a delegate of its own type.
/// Initial C# idea by: Bertrand Le Roy (MSFT)
/// </summary>
/// <param name="action">functor</param>
/// <param name="options">optional parameters</param>
/// <returns>Itself</returns>
public delegate CallStream<T>
CallStream<T>(T action, params object[] options);
[/sourcecode] I think I can say that the whole implemention of the C# CallStream binding , is in the three delegates above.
Now, let me show you the usage of the above, applied to two different kinds of call streams : a functional kind and keyword driven streaming kind. Code bellow explains the best. Here is the trivial test unit which implements a CallStream for streaming calls to functions.
[sourcecode language=”csharp” light=”false”] [TestClass] public sealed class function_calls_streaming
{
/// <summary>
/// this callStream bridge is just an
/// simple function invoker (aka applicator) for the user provided function
/// and 0 or more optional arguments
/// </summary>
void function_applicator(TheFunction function, object[] paramz)
{
function.Invoke(paramz);
}

/// <summary>
/// An implementation of the CallStream delegate
/// where each call must begin with a function of type "TheFunction"
/// All of the parameters are simply passed to the bridge method.
/// </summary>
/// <returns>itself</returns>
CallStream<TheFunction> function_streamer(TheFunction function, params object[] options)
{
function_applicator(function, options);
return function_streamer;
}

[TestMethod] public void function_streamer_test()
{
function_streamer
(p => Console.WriteLine(p), "Lambda Dumper Argument")
(Behind.Dump, DateTime.Now.ToLocalTime().ToString())
(Behind.DumpFooAndBar, false, 2)
(p => Behind.Dump(System.Collections.ArrayList.Repeat(p, 3).ToArray()), "Done.");

Assert.AreEqual(1, 1);
}
}
[/sourcecode] I could do it (and I did it) with nested type arguments to generic delegates , and other snazzy C# constructs, but at the end I decided to keep it simple.
Please note that “function_streamer” can be replaced with an different StramCallBridge implementation, and thus allow us to create a whole familly of “functional” CallStream’s . Perhaps that could be also second type argument to generic CallStream. Perhaps. But I decided it will be an overkill.

And yes, the code in this post does not require VisualStudio 2010 or C#4.0. Also an deliberate decision of mine.

Here is the next implementation of a CallStream, which is for situations where one needs or wants to communicate with her implementation that is hidden behind, through some kind of micro langauge (maybe some simple query language) , using the keywords+parameters paradigm.
[sourcecode language=”csharp” light=”false”] [TestClass] public sealed class keywords_and_parameters_call_stream
{
/// <summary>
/// This callStream bridge is keyword handler
/// It deals also with 0 or more optional arguments for each keyword
/// </summary>
void keyword_applicator(string keyword, params object[] paramz)
{
Behind.Dump("KEYWORD: " + keyword);
if (keyword.Equals("dump", StringComparison.CurrentCultureIgnoreCase))
{
Behind.Dump(paramz);
} else
if (keyword.Equals("dumpfooandbar", StringComparison.CurrentCultureIgnoreCase))
{
Behind.DumpFooAndBar(paramz);
}
else
{
Behind.Dump("Unknown keword!");
}
}

/// <summary>
/// An implementation of the CallStream delegate
/// where each call must begin with a keyword of type string
/// followed with 0 or more optional parameters, of any type
/// All of the parameters are passed to the bridge method.
/// </summary>
/// <returns>itself</returns>
CallStream<string> keyword_streamer(string keyword, params object[] options)
{
keyword_applicator(keyword, options);
return keyword_streamer;
}

[TestMethod] public void keyword_streamer_test()
{
keyword_streamer
("Dump", DateTime.Now.ToLocalTime().ToString())
("DumpFooAndBar", false, 2)
("Fantasy") ;

Assert.AreEqual(1, 1);
}
}
[/sourcecode] Please note how we can pass illegal keywords. They will be ignored, until we decide to implement an response to them. Inside a keyword handler we are using. And of course we can easily switch different keyword handlers, perhaps for different languages, etc.

Conclusion

I would not dare to call this trivial, but I think it is rather simple to implement different kinds CallStream and CallStreamBridge for your different and specific C# projects.

–DBJ

PS: here is the “Behind” class used above.
[sourcecode language=”csharp” light=”false”] /// <summary>
/// The "state" of the application is "hidden behind"
/// Here are the functions that are written in such a way
/// that they can be used by "functional_streamer"
/// because their declarations conform to the "TheFunction" delegate
/// which is used to compose that CallStream implementation
/// NOTE: this makes them some kind of monads, probably
/// </summary>
internal sealed class Behind
{
public static void Dump(params object[] options)
{
foreach (var j in options)
{
Console.WriteLine(j);
}
}

public static void DumpFooAndBar(params object[] options)
{
Console.WriteLine("Foo is: {0}, and bar is: {1}.",
options.Length > 0 ? options[0] : "NULL",
options.Length > 1 ? options[1] : "NULL"
);
}
}
[/sourcecode]

Comments are closed.