Tales from the Evil Empire

Bertrand Le Roy's blog

News


Bertrand Le Roy

BoudinFatal's Gamercard

Tales from the Evil Empire - Blogged

Blogs I read

My other stuff

Archives

March 2010 - Posts

A C# implementation of the CallStream pattern

(c) Bertrand Le Roy Dusan published this interesting post a couple of weeks ago about a novel JavaScript chaining pattern:

http://dbj.org/dbj/?p=514

It’s similar to many existing patterns, but the syntax is extraordinarily terse and it provides a new form of friction-free, plugin-less extensibility mechanism.

Here’s a JavaScript example from Dusan’s post:

CallStream("#container")
(find, "div")
(attr, "A", 1)
(css, "color", "#fff")
(logger);

The interesting thing here is that the functions that are being passed as the first argument are arbitrary, they don’t need to be declared as plug-ins. Compare that with a rough jQuery equivalent that could look something like this:

$.fn.logger = function () { /* ... */ }
$("selector")
    .find("div")
    .attr("A", 1)
    .css("color", "#fff")
    .logger();

There is also the “each” method in jQuery that achieves something similar, but its syntax is a little more verbose.

Of course, that this pattern can be expressed so easily in JavaScript owes everything to the extraordinary way functions are treated in that language, something Douglas Crockford called “the very best part of JavaScript”.

One of the first things I thought while reading Dusan’s post was how I could adapt that to C#. After all, with Lambdas and delegates, C# also has its first-class functions.

And sure enough, it works really really well. After about ten minutes, I was able to write this:

CallStreamFactory.CallStream
  (p => Console.WriteLine("Yay!"))
  (Dump, DateTime.Now)
  (DumpFooAndBar, new { Foo = 42, Bar = "the answer" })
  (p => Console.ReadKey());

Where the Dump function is:

public static void Dump(object options) {
    Console.WriteLine(options.ToString());
}

And DumpFooAndBar is:

public static void DumpFooAndBar(dynamic options) {
    Console.WriteLine("Foo is {0} and bar is {1}.",
options.Foo, options.Bar); }

So how does this work? Well, it really is very simple. And not. Let’s say it’s not a lot of code, but if you’re like me you might need an Advil after that. First, I defined the signature of the CallStream method as follows:

public delegate CallStream CallStream
(Action<object> action, object options = null);

The delegate define a call stream as something that takes an action (a function of the options) and an optional options object and that returns a delegate of its own type. Tricky, but that actually works, a delegate can return its own type.

Then I wrote an implementation of that delegate that calls the action and returns itself:

public static CallStream CallStream
(Action<object> action, object options = null) {
action(options); return CallStream; }

Pretty nice, eh? Well, yes and no. What we are doing here is to execute a sequence of actions using an interesting novel syntax. But for this to be actually useful, you’d need to build a more specialized call stream factory that comes with some sort of context (like Dusan did in JavaScript).

For example, you could write the following alternate delegate signature that takes a string and returns itself:

public delegate StringCallStream
StringCallStream
(string message);

And then write the following call stream (notice the currying):

public static StringCallStream
CreateDumpCallStream(string dumpPath) {
StringCallStream str = null; var dump = File.AppendText(dumpPath); dump.AutoFlush = true; str = s => { dump.WriteLine(s); return str; }; return str; }

(I know, I’m not closing that stream; sure; bad, bad Bertrand)

Finally, here’s how you use it:

CallStreamFactory.CreateDumpCallStream(@".\dump.txt")
    ("Wow, this really works.")
    (DateTime.Now.ToLongTimeString())
    ("And that is all.");

Next step would be to combine this contextual implementation with the one that takes an action parameter and do some really fun stuff.

I’m only scratching the surface here. This pattern could reveal itself to be nothing more than a gratuitous mind-bender or there could be applications that we hardly suspect at this point. In any case, it’s a fun new construct. Or is this nothing new? You tell me… Comments are open :)

NoSQL is not about object databases

(c) Bertrand Le Roy 2008 NoSQL as a movement is an interesting beast. I kinda like that it’s negatively defined (I happen to belong myself to at least one other such a-community). It’s not in its roots about proposing one specific new silver bullet to kill an old problem. it’s about challenging the consensus.

Actually, blindly and systematically replacing relational databases with object databases would just replace one set of issues with another.

No, the point is to recognize that relational databases are not a universal answer -although they have been used as one for so long- and recognize instead that there’s a whole spectrum of data storage solutions out there.

Why is it so hard to recognize, by the way? You are already using some of those other data storage solutions every day. Let me cite a few:

  • The file system
  • Active Directory
  • XML / JSON documents
  • The Web
  • e-mail
  • Logs
  • Excel files
  • EXIF blobs in your photos
  • Relational databases
  • And yes, object databases

It’s just a fact of modern life. Notice by the way that most of the data that you use every day is unstructured and thus mostly unsuitable for relational storage. It really is more a matter of recognizing it: you are already doing NoSQL.

So what happens when for any reason you need to simultaneously query two or more of these heterogeneous data stores? Well, you build an index of sorts combining them, and that’s what you query instead.

Of course, there’s not much distance to travel from that to realizing that querying is better done when completely separated from storage.

So why am I writing about this today?

Well, that’s something I’ve been giving lots of thought, on and off, over the last ten years. When I built my first CMS all that time ago, one of the main problems my customers were facing was to manage and make sense of the mountain of unstructured data that was constituting most of their business. The central entity of that system was the file system because we were dealing with lots of Word documents, PDFs, OCR’d articles, photos and static web pages. We could have stored all that in SQL Server. It would have worked. Ew. I’m so glad we didn’t.

Today, I’m working on Orchard (another CMS ;). It’s a pretty young project but already one of the questions we get the most is how to integrate existing data.

One of the ideas I’ll be trying hard to sell to the rest of the team in the next few months is to completely split the querying from the storage. Not only does this provide great opportunities for performance optimizations, it gives you homogeneous access to heterogeneous and existing data sources. For free.

FluentPath now on CodePlex

My FluentPath library is now available on CodePlex. I’ve also modified the code so that it can now be compiled against .NET 3.5SP1 and not just .NET 4.0.

http://fluentpath.codeplex.com/

Binding a select in a client template

(c) Bertrand Le Roy 2008 I recently got a question on one of my client template posts asking me how to bind a select tag’s value to data in client templates. I was surprised not to find anything on the web addressing the problem, so I thought I’d write a short post about it.

It really is very simple once you know where to look. You just need to bind the value property of the select tag, like this:

<select sys:value="{binding color}">

If you do it from markup like here, you just need to use the sys: prefix. It just works.

Here’s the full source code for my sample page:

<!DOCTYPE html>
<html>
<head>
  <title>Binding a select tag</title>
  <script
src=http://ajax.microsoft.com/ajax/beta/0911/Start.js
type
="text/javascript"></script> <script type="text/javascript"> Sys.require(Sys.scripts.Templates, function() { var colors = [
"red", "green", "blue",
"cyan", "purple", "yellow"
]; var things = [ { what: "object", color: "blue" }, { what: "entity", color: "purple" }, { what: "thing", color: "green" } ]; Sys.create.dataView("#thingList", { data: things, itemRendered: function(view, ctx) { Sys.create.dataView( Sys.get("#colorSelect", ctx), { data: colors }); } }); }); </script> <style type="text/css"> .sys-template {display: none;} </style> </head> <body xmlns:sys="javascript:Sys"> <div> <ul id="thingList" class="sys-template"> <li> <span sys:id="thingName" sys:style-color="{binding color}" >{{what}}</span> <select sys:id="colorSelect" sys:value="{binding color}" class="sys-template"> <option sys:value="{{$dataItem}}" sys:style-background-color="{{$dataItem}}" >{{$dataItem}}</option> </select> </li> </ul> </div> </body> </html>

This produces the following page:Binding Select

Each of the items sees its color change as you select a different color in the drop-down.

Other details worth noting in this page are the use of the script loader to get the framework from the CDN, and the sys:style-background-color syntax to bind the background color style property from markup.

Of course, I’ve used a fair amount of custom ASP.NET Ajax markup in here, but everything could be done imperatively and with completely clean markup from the itemRendered event using Sys.bind.

FluentPath: a fluent wrapper around System.IO

(c) Bertrand Le Roy 2005 .NET is now more than eight years old, and some of its APIs got old with more grace than others. System.IO in particular has always been a little awkward. It’s mostly static method calls (Path.*, Directory.*, etc.) and some stateful classes (DirectoryInfo, FileInfo). In these APIs, paths are plain strings.

Since .NET v1, lots of good things happened to C#: lambda expressions, extension methods, optional parameters to name just a few. Outside of .NET, other interesting things happened as well. For example, you might have heard about this JavaScript library that had some success introducing a fluent API to handle the hierarchical structure of the HTML DOM. You know? jQuery.

Knowing all that, every time I need to use the stuff in System.IO, I cringe. So I thought I’d just build a more modern wrapper around it. I used a fluent API based on an essentially immutable Path type and an enumeration of such path objects. To achieve the fluent style, a healthy dose of lambda expressions is being used to act on the objects.

Without further ado, here’s an example of what you can do with the new API. In that example, I’m using a Media Center extension that wants all video files to be in their own folder. For that, I need a small tool that creates directories for each video file and moves the files in there. Here’s the code for it:

Path.Get(args[0])
    .GetFiles(p =>
        new string[] {
            ".avi", ".m4v", ".wmv",
            ".mp4", ".dvr-ms", ".mpg", ".mkv"
        }.Contains(p.Extension))
    .CreateDirectory(p => 
        p.Parent
         .Combine(p.FileNameWithoutExtension))
    .Previous()
    .Move(p =>
        p.Parent
         .Combine(p.FileNameWithoutExtension)
         .Combine(p.FileName));

FluentPath1 This code creates a Path object pointing at the path pointed to by the first command line argument of my executable. It then selects all video files. After that, it creates directories that have the same names as each of the files, but without their extension. The result of that operation is the set of created directories. We can now get back to the previous set using the Previous method, and finally we can move each of the files in the set to the corresponding freshly created directory, whose name is the combination of the parent directory and the filename without extension.

The new fluent path library covers a fair part of what’s in System.IO in a single, convenient API. Check it out, I hope you’ll enjoy it. Suggestions are more than welcome. For example, should I make this its own project on CodePlex or is this informal style just OK? Anything missing that you’d like to see? Is there a specific example you’d like to see expressed with the new API? Bugs?

The code can be downloaded from here (this is under MS-PL license):
http://weblogs.asp.net/blogs/bleroy/Samples/FluentPath.zip

UPDATE: updated the license; modified the sample code to use Contains; renamed and refactored Select to be overloads of GetFiles, GetDirectories and GetFileSystemEntries. I did not rename Select to Where because this is *not* filtering the current set, it is creating a new one from the contents of the current path.

More Posts