Wednesday, July 22, 2009

Introducing Rx (Linq to Events)

It’s the most wonderful time of the year: a new version of the Silverlight Toolkit has been released alongside Silverlight 3.  This release of the Toolkit has a lot of goodies including a new TreeMap control, a Rating control (written by yours truly), and a useful collection of extensions methods for TreeView.  That said this post is not really about the Toolkit.   Buried deep in the bin folder of the Silverlight Toolkit Unit Tests is a hidden gem: The Rx Framework (System.Reactive.dll).  If you glanced quickly you’d miss it altogether but it’s one of the most exciting additions to the .NET framework since Linq.

Stating the Obvious: Asynchronous Programming is Hard

Developers tend to avoid asynchronous programming if possible because it makes our programs non-deterministic and obscure our code’s intent in a sea of callbacks.  However the truth is that asynchronous programming has become an essential part of application development.  Client apps have always needed to use asynchronous methods to keep the user interface responsive.  As a matter of fact Silverlight developers don’t have any choice in the matter because Silverlight doesn’t include any blocking IO calls.  Connected apps also need to take advantage of asynchronous programming to improve scalability.  Mashups, apps cobbled together from web services, often need to retrieve data from multiple sources in a particular order. 

Clearly we need to write asynchronous code to create modern, connected applications, but how to do it in such a way that our code remains clear and maintainable?

Introducing the Rx Framework

The IEnumerable Interface

We’re all familiar with the IEnumerable interface.  Almost every collection implements it and we use it every time we write a foreach.  Most of us are also pretty comfortable using Linq to query IEnumerables.  Linq is a series of extension methods used to manipulate sequences.  Here’s a simple example:

int[] numbers = new int[]{20,31,5,16,22};
IEnumerable<int> numbersSmallerThan20 = numbers.Where(number => number < 20);

The resulting numbersSmallerThan20 sequence looks like this when visualized:

5, 16, break

In addition to finite sequences it can sometimes be useful to create sequences that never end.  Take this method that returns an infinite sequence of integers:

IEnumerable<int> NaturalNumbers()
{
     int number = 0;
     while(true)
    {
        yield return number;
        number++;
    }
}

When visualized this sequence looks like this:

0,1,2,3,4,5,6…

Enumerable’s are sequences of data that we pull from a data source.  We don’t always pull data though.  Often it is pushed onto us and we must react appropriately.  This is called “Reactive Programming.”

Reactive Programming

Reactive programs are ubiquitous.  We use reactive programming every time we register a handler with an event or a specify a call back for an asynchronous operation.  In this example I register a handler for the mouse move event of a button.  The handler prints out the location of the mouse when it is called.

 

button.MouseMove += (o, mouseEventArgs) => Debug.Writeline(“You moved the mouse to {0}”, mouseEventArgs.GetPosition(button));


Every time the mouse event is fired our callback method is invoked and we are passed some information about the event. 

“You moved the mouse to 20,3”

“You moved the mouse to 33,12”

“You moved the mouse to 44,18”

Another form of reactive programming is running an asynchronous method and passing it a callback method to invoke when it’s finished.  This is how we keep our programs responsive during long-running operations.  Here’s an example:

DownloadFile(“http://www.jeffwilcox.com”, (byteArray) => Debug.WriteLine(“This file is {0} bytes long.”, byteArray.Length);

When this method finishes downloading a file it passes the data to our callback function giving us the following result:

“This file is 12323 bytes long.”

We’re all used to doing reactive programming by specifying methods that are called at unpredictable times, but what if there was a different way to think about reactive programming?  What if we thought of each piece of data passed to a reactively-called method as an item in a sequence?

Events and Callbacks are Sequences of Data!

The data passed to event handlers and callbacks can be thought of as sequences of data that are “pushed” at you rather than “pulled.”  Every time an event is fired we get “pushed” a new piece of data: the EventArgs.  Similarly when a callback is invoked it is typically “pushed” the result of the asynchronous method.  You can think of an event as a sequence of EventArgs that never ends just like the NaturalNumbers sequence.  If you were to visualize the mouse move event as a sequence it would look like this:

new MouseEventArgs(new Point(20,3)), new MouseEventArgs(new Point(33,12)), new MouseEventArgs(new Point(44,18))…

Similarly the asynchronous DownloadFile method can be viewed as a “push” sequence of data with only one entry:

new byte[]{23,211,33,23…}, break

The Rx team has discovered that pull sequences and push sequences are “dual.”  That is to say, any operation you can perform on “pull” sequences can also be performed on “push” sequences.  This is quite a revelation.  To put things in perspective it’s been 13 years since Design Patterns was published and we’ve only now realized that the Observable pattern and the Iterator pattern are actually the same pattern.

Although reactive “push” sequences are fundamentally the same as “pull” sequences the IEnumerable interface can’t be used for reactive sequences because it blocks.  We need a new interface with non-blocking methods that correspond exactly to the blocking methods on IEnumerable.  We need…

The IObservable/IObserver Interface

Despite the fact that they may look somewhat different on the surface the IObservable/IObserver pair of interfaces are the non-blocking equivalents of IEnumerable/IEnumerator.

clip_image001

To help you understand how they are equivalent let’s take a look at a simple example of traversing a pull sequence.  You enumerate an IEnumerable by requesting an IEnumerator.  As you call MoveNext the IEnumerator “pulls” data from the IEnumerable, usually by invoking its methods.

IEnumerator<int> numberEnumerator = new int[]{1,2,3};
while(numberEnumerator.MoveNext())
{
     Debug.WriteLine(“{0}”, numberEnumerator.Current);
}

Debug.WriteLine(“all done.”);

This prints:

1
2
3
all done.

To traverse an IObservable you go through the same actions as an IEnumerable but in reverse.  You create an IObserver, give it to an IObservable, and the IObservable “pushes” data into the IObserver by invoking its methods.  When an IObservable invokes the “OnNext” method on an Observer it is equivalent to an IEnumerable method using the yield keyword to give information to an IEnumerable.  Similarly when an IObservable invokes the “OnCompleted” method on an Observer it is equivalent to an IEnumerable using the break keyword to indicate that there is no more data.

Let’s define a NumbersObserver which converts a “pull” sequence of numbers into a “push” sequence as well as an observer that listens to our NumbersObserver and prints its contents.

 

internal class AnonymousDisposable : IDisposable
{

    internal Action Action {get; internal set;}

    void IDisposable.Dispose()
    {
        this.Action();
    }
}

class NumbersObservable : IObservable<int>
{
    public NumbersObservable(IEnumerable<int> numbers)
    {
        this._numbers = numbers;
    }

    private IEnumerable<int> _numbers;

    public IDisposable Subscribe(IObserver<int> observer)
    {
         foreach(int number in _numbers)
        {
             observer.OnNext(number);
        }
        observer.OnCompleted();

        return new AnonymousDisposable { Action = () => { ; // do nothing because we’ve already called OnCompleted() } }; 
    }
}

class DebugObserver : IObserver<int>
{
    public void OnNext(int value)
    {
        Debug.WriteLine(“{0}”, value);
    }

    public void OnCompleted()
    {
        Debug.WriteLine(“all done.”);
    }

    public void OnError(Exception ex)
    {
        Debug.WriteLine(“Whoops exception, I’d better throw.”)
        throw ex;
    }
}

Now let’s use these classes to create a “push” version of our “pull” example:

new NumbersObservable(new[]{2,3,4}).Register(new DebugObserver());

This prints…

1
2
3
all done.

“Whoa, whoa!  Isn’t this pretty complicated?”

Don’t worry.  This example above is just to demonstrate the interplay between the interfaces.  Most of the time you won’t have to implement your own Observable or Observer.  Rx includes lots of methods for constructing observables and observers.  Using Rx extension methods I can rewrite the code above like so:

new[]{1,2,3}.ToObservable().Subscribe(number => Debug.WriteLine(“{0}”, number));

“What’s with the IDisposable object?”

The IDisposable object is returned by an Observable when you register an observer with it.  When you invoke the Dispose method on the registration object the observer will stop listening to the observable for data.  This is the active equivalent of passively not calling MoveNext() anymore in the middle of a sequence.  Rather than invoke the Dispose method directly you will most often have it invoked for you by Rx.  In the following example the TakeWhile method will invoke Dispose under the hood to detach from an observable as soon as a number larger than 10 is returned.

var numbersSmallerThanTen = Enumerable.Range(0,100).ToObservable().TakeWhile(x => x <= 10);

Here’s an example of invoking Dispose explicitly to detach from an event which has been converted to an Observable:

// Use an Rx method to convert an event to an Observable
IObservable<Event<MouseEventArgs>> mouseMoveEventObservable = Observable.FromEvent<MouseEventArgs>(myControl, “MouseMove”);

// register a handler with the event using an overload that accepts a lambda instead of an Observer
IDisposable registration = mouseMoveEventObservable.Subscribe(mouseMoveEvent => Debug.Write(“The mouse was moved.”));

// stop listening to the event
registration.Dispose();

“What about the OnError method?  I don’t see an equivalent for that in IEnumerable or IEnumerator either.”

When errors occur in asynchronous operations the exception must be passed to the callback method so that the callback method can handle it.  That’s why this method exists in IObservable but seems to have no equivalent in IEnumerable.  In IEnumerable it is implicit because you can use try/catch.

Linq to IObservable

Now that we understand that an IObservable is just a “push” version of IEnumerable it just be obvious that all of the familiar Linq methods apply to it.  In fact it is equally appropriate to use query syntax on “pull” sequences and “push” sequences.  Both are queries in the strictest sense and the fact that a sequence is push or pull is orthogonal.  Let’s analyze a typical Linq query:

IEnumerable<Point> points =
     from x in Enumerable.Range(0, 2)
     from y in Enumerable.Range(0, 2)
     select new Point(x,y);

A verbal description of this query might be:

“For each x in the sequence [0 to 1] get each y in the sequence [0 to 1] and create a new point for each pair of values.”

The result of course is:

0,0
0,1
1,0
1,1

Now let’s contrast this with an Rx query that creates a dragging event for a Silverlight/WPF control:

IObservable<Event<MouseEventArgs>> draggingEvent =
     from mouseLeftDownEvent in control.GetMouseLeftDown()
     from mouseMoveEvent in control.GetMouseMove().Until(control.GetMouseLeftUp())
     select mouseMoveEvent;

A verbal description of this query might be:

“For each mouse left down event, get each mouse move event and return it until the next mouse left up event occurs.”

As you can see, using “from” allows us to declaratively sequence events.  The alternative would be to create a state machine, setting a flag when the mouse button is pressed and then behaving differently when the mouse is moved and that flag is set.  With Rx the code for the drag event is self-contained and involves no variable mutation.

With Linq to IEnumerable we transform and combine sequences of data to create a sequence containing exactly the data we need.  Then we traverse that sequence and do something with the data.  With  Linq to IObservable we can transform and combine events and async callbacks to create the precise event we’re interested in.  Then we register a handler and do something with the data.

Silverlight Toolkit Unit Test Code Written with Rx

The Silverlight Toolkit team is using Rx to write reliable, event-based asynchronous tests.  This is essential as the elements in a control’s visual tree are created asynchronously, forcing us to wait for an event in order to confirm they were created appropriately. Let’s take a look at a test for Rating that uses Rx.

This test ensures that the Actual Value of a RatingItem is %100 when its parent Rating is %100.  This is tricky because when you change the value of rating it animates to the new value using an internal storyboard.  I have to wait for ActualValue to be animated to the Value property before I examine the RatingItem.

The test creates a Rating control, places it on screen, and waits for LayoutUpdated to ensure that the rating items are generated.  Then it asynchronously sets the value of rating to 1.0.  As the ActualValue of the Rating changes, the various RatingItems will have their ActualValue’s set accordingly depending on their index.  The test needs to wait until the Rating’s ActualValue reaches Value before checking to make sure the ActualValue of the last rating item is 1.0.

 

Rating rating = new Rating();
IObservable<Unit> test =                             // Unit is an object that represents null.
    ObservableExtensions
        .DoAsync(() => TestPanel.Children.Add(rating))
        .WaitFor(TestPanel.GetLayoutUpdated())     // Extension method GetLayoutUpdated converts the event to observable
        .DoAsync(() => rating.Value = 1.0)        // Calls the Ignite EnqueueCallback method
        .WaitFor(                                 // waits for an observable to raise before going on
            // listen to all the actual value change events and filters them until ActualValue reaches Value
            rating                          
            .GetActualValueChanged()        // extension method that converts ActualValueChanged event to IObservable
            .SkipWhile(actualValueChangedEvent => actualValueChangedEvent.EventArgs.NewValue != rating.Value))
        // check to make sure the actual value of the rating item is set appropriately now that the animation has completed
        .Assert(() => rating.GetRatingItems().Last().ActualValue == 1.0) // crawls the expression tree and makes a call to the appropriate Assert method

Test.Subscribe(() => TestPanel.Children.Remove(rating));    //run the test and clean up at the end.

The code above uses a variety of extension methods we built to manipulate observable objects.  You can use these libraries in your own unit tests by downloading the Silverlight Toolkit sources.

Always Useing IObservable for New Asynchronous APIs

The IObservable/IObserver interfaces are in .NET framework 4.0.  I want to stress that IObservable is the new asynchronous programming pattern in .NET. It supplants the Begin/EndInvoke pattern as well as the event-based asynchronous pattern.  Simple run of thumb: if the method is asynchronous, return an IObservable. *

*A correction here.  It is still perfectly acceptable to use Begin/End Invoke or the event-based asynchronous pattern.  Large portions of the framework use these patterns and will continue to do so for the sake of consistency.

Exposing IObservable is like putting lighting in a bottle.  Developers can open it up and get access to a galaxy of Linq methods they can use to combine and sequence them with other IObservables.  My hope is that eventually API’s exposing IObservable will be just as common as those exposing IEnumerable.

Erik Meijer Strikes Again

Rx is the brainchild of Erik Meijer, the father of Linq and recent recipient of the Outstanding Technical Leadership award at Microsoft.  Erik is the reason I chose to work for Microsoft.  With the introduction of Rx and his work on Linq and Haskell he has profoundly changed the way I approach software development twice in four years – an incredible feat.  Thanks to Meijer, Microsoft does a better job than anyone of taking bleeding-edge functional programming research and productizing it.  The Rx team also includes my favorite blogger, Wes Dyer whose blog posts opened my eyes to what an incredibly versatile language C# is.

After using it for the last few months it’s now impossible to imagine doing Silverlight development without Rx.  As of today the only place you can get it is in the Silverlight Toolkit sources.  Take a look.  If you are comfortable with Linq programming you’ll find it to be extremely powerful.

Thursday, July 9, 2009

Introducing the Rating Control

Boys and girls, its the most wonderful time of the year: a new version of Silverlight is shipping.  Silverlight 3 shipped today along with a refresh of the Silverlight Toolkit.  For this release I had the pleasure of writing the Rating control which is available in both the Silverlight 2 and 3 versions of the Toolkit.  In this post I'll give you a high level overview of how Rating works and how you can customize it.

Using Rating

The Rating control is located in the System.Windows.Controls namespace in System.Windows.Controls.Input.Toolkit.dll.  Once you've added a XAML namespace you can create a Rating like this...

<inputToolkit:Rating ItemCount="5" />

This will create a Rating control with five stars:

rating

Giving Rating a Value

The Rating control has a Value property which is a ratio from 0 to 1.  The Value property is a nullable double.  In other words the Value property is either between 0% and 100% or it is null.

The Rating control has two selection modes: Continuous and Individual.  In Continuous mode (the default) the control behaves the way most star-based Rating controls do: filling the first two stars and half of the middle one.

<inputToolkit:Rating ItemCount="5" Value="0.5" SelectionMode="Continuous" />

continuous

However in individual mode, the stars leading up to the middle star are not filled:

<inputToolkit:Rating ItemCount="5" Value="0.5" SelectionMode="Individual" />

individual

Individual mode is useful when you want to offer discrete selection options:

individualcustom

Adding Rating Items

Rating is an ItemsControl with an ItemCount convenience property which adds instances of RatingItem to the Items collection.  Therefore this...

<inputToolkit:Rating ItemCount="5" />

...is equivalent to this...

<inputToolkit:Rating> <inputToolkit:Rating.Items> <inputToolkit:RatingItem /> <inputToolkit:RatingItem /> <inputToolkit:RatingItem /> <inputToolkit:RatingItem /> <inputToolkit:RatingItem /> </inputToolkit:Rating.Items> </inputToolkit:Rating>

...and this:

var rating = new Rating { ItemsSource = new[]{"", "", "", "", ""} };

ItemCount is convenient if you don't need to bind your rating items to an underlying data source or otherwise vary their appearance.  However since RatingItems are content controls if you do bind to a data source your data will be displayed below the RatingItem. 

var rating = new Rating { SelectionMode = RatingSelectionMode.Individual, ItemsSource = new[]{"Hate", "Bored", "Good", "Great", "Love"} };

The Template

The Rating ItemsControl uses instances of the RatingItem class as its item container.  RatingItem inherits from ContentControl and its template contains an instance of the LinearClipper control.  The LinearClipper control is used to hide a portion of the star in the RatingItem template.

ratingtemplate

In addition to the common visual states the RatingItem control has a "Fill States" visual state group which contains the following states: "Empty", "Partial", and "Filled."

The LinearClipper has a property ExpandDirection which can be used to determine whether it expands Up, Down, Left, or Right.  By changing this property along with the ItemPanelTemplate property of Rating you can customize Rating to display and reveal stars vertically.

As Rating is an ItemsControl all the tricks you already know to customize an ItemsControl's appearance apply.  I won't rehash how to style an ItemsControl here, there's plenty of information on MSDN.  For comprehensive examples of re-templated Rating controls you can take a look at the Rating sample page in Silverlight Toolkit samples.

Rate Rating

Rating is being released under the "Preview" quality band.  That means we're looking for feedback on ways in which we can improve it.  Try it out and let us know what you think on the CodePlex forums.

Tuesday, June 2, 2009

Better Unit Tests with Test.Assert() for NUnit/VSTT/SUTF

It’s been over ten years since Kent Beck created SUnit, the first unit testing framework for SmallTalk.  Since then, hundreds of unit testing frameworks have been created in its image, one for nearly every platform and programming language.  JUnit, the open-source Java unit testing framework, begat NUnit, the popular .NET port, which inspired Visual Studio Team Test, which was ported to the Silverlight Unit Testing Framework, and it was good. 

For the most part NUnit’s and VSTT’s API’s are the same as those of JUnit. This is probably a good thing because it makes it much easier for Java developers to adopt .NET.  It was also a natural decision given how similar C# and Java were when NUnit was created. However .NET programming languages have evolved rapidly in the last few years.  Have you ever stopped to wonder whether the API’s for the .NET unit testing frameworks should still be so similar to those of JUnit?  

Nowadays C# and VB.NET are capable of some very powerful code transformations.  Despite the fact that .NET developers are conditioned to think of API’s and programming languages as separate the reality is not so simple.  The capabilities of programming languages tend to influence the design of API’s. The question is this: Can we use the advanced features of .NET programming languages to create better unit testing API’s?

“What’s wrong with Unit Testing API’s?  They’re pretty straightforward.”

There are three things wrong with the assertion API’s used by the major unit testing frameworks:

1.  You Can’t Use Expressions

Let’s take a look at a typical Visual Studio Team Test.

[TestMethod]
public void TestStackIsEmptyWhenCreated()
{
    Stack emptyStack = new Stack();
    Assert.AreEqual(emptyStack.Count, 0, "Stack is not empty.");
}

Ask yourself this question: Is the AreEqual method really necessary?  Our programming languages already have a rich set of comparison operators.  Most of us are accustomed to writing debug assertions this way:

Debug.Assert(emptyStack.Count == 0, "Stack is not empty.");

Operators make common operations more recognizable to the human eye. If comparison operators are easier to read than the Assert methods why do we use the latter in our unit tests? 

The reason is that we want descriptive failure messages in the event our test fails. If we fail the test above by adding an item to the stack we get a failure message much like this:

TestStackIsEmptyWhenCreated failed.  Values are not equal. Expected 0, got 1. Stack is not empty.

Notice that in addition to including what type of comparison operation that failed the framework also provides the values being tested.  If we were to specify an expression (as in the Debug.Assert example above) it would get compiled into executable code and by the time the UT framework got our expression it would be a black box.  As a result it would be impossible to determine what kind of comparison we were attempting or the values of the arguments.  Therefore Assert methods are necessary, despite the fact that they are ugly.

2.  Assert.AreEqual vs. Assert.AreSame

Another problem caused by the inability to use expressions is that we must be explicit about whether we want to use value or reference comparisons.  Have you ever used Assert.AreEqual when you should’ve used Assert.AreSame or vice versa?  In some circumstances this can lead to false positives or negatives.  It is especially annoying for C# and F# developers as we are used to our compilers choosing the appropriate comparison type for us based on context.

3.  Redundant Assertion Messages

It is generally considered good practice to add a custom assertion message to provide more context in the event a test fails.  This is especially important if a test makes multiple calls to the same Assert method.  Let’s say we left the assertion message out of our unit test:

[TestMethod]
public void TestStackIsEmptyWhenCreated()
{
    Stack emptyStack = new Stack();
    Assert.AreEqual(emptyStack.Count, 0);
}

The resulting message would be:

TestStackIsEmptyWhenCreated failed.  Values are not equal. Expected 0, got 1.

Of course this is a very simple test so you could probably infer what went wrong.  It is a little cryptic though.  In a larger test it would be much more difficult to isolate the issue.

So what’s wrong with assertion messages?  They’re superfluous.  Ask yourself this question: If you didn’t have to specify a message for the Unit Test Framework to display on failure, would you add that message as a comment above the line of code? 

// Testing whether stack is empty
Assert.AreEqual(emptyStack.Count, 0);

The answer is usually no.  Assuming you’ve properly named your variables it is rarely necessary to comment assertions.  In an ideal world our Unit Testing Framework would output the line of code that failed, just as our compilers do when they encounter syntax errors.  This would make most assertion messages redundant.

The Root Problem

All of these issues are caused by the same root problem.  Conceptually Unit Testing frameworks are an extension of your compiler.  Compilers report static errors such as malformed code and type mismatches and unit testing frameworks report run-time errors such as unexpected values.  The reason why Unit Testing API’s are so clunky is that our Unit Testing frameworks don’t have access to as much information as our compiler does.  Compilers have access to the expression trees generated by our code.  They can analyze the code and determine what type of comparison we are attempting, and whether it is a value or reference comparison.  If the compiler encounters an error it can print the exact line of code or expression responsible.

What if there was a way to make our Unit Testing Frameworks as smart as our compilers?

Introducing Test.Assert()

Turns out it is possible to express assertions as expressions and get all the feedback provided by the Assert methods when a test fails (and even more).

Assertions as Expressions

Let’s rewrite our unit test using the Test.Assert() method:

using Unfold.Testing.VSTT;

// snip...

[TestMethod]
public void TestStackIsEmptyWhenCreated()
{
    Stack emptyStack = new Stack();
    emptyStack.Push("an item that shouldn't be here.");
    Test.Assert(() => emptyStack.Count == 0);
}

When we run this test and it fails we’ll get a message resembling this:

TestStackIsEmptyWhenCreated failed.  Values are not equal. Expected 0, got 1. emptyStack.Count = 0

Notice that we get the same failure message as Assert.AreEqual in addition to the expression responsible for the failure!

Compound Expressions

Now that we can express assertions as expressions you may be wondering whether it is possible to express several assertions in a single compound expression.  With Test Extensions it’s as easy as using the “and” operator.

Test.Assert(() => customer.Name != null && customer.Name != “”);

Now our assertions are much easier to read as well as shorter!

“Hold on.  Won’t using compound expressions make it harder to figure out which expression failed?”

No.  Test.Assert doesn’t display the line of code that fails, it displays the expression that fails.  For example if, in the test above, the customer’s name was an empty string we’d get the following failure messages:

TestCustomerDefaultPropertyValues failed.  Values are same.  Expected not “”, got “”.  customer.Name != “”

“Okay, but what if I still want to specify a custom assertion message?”

No problem.  Test Assert has an overload for that:

Test.Assert(() => customer.Name != null && customer.Name != “”, "Customer name is null or empty.");


“Is it available for my Unit Testing Framework?”

Yes – assuming you’re using NUnit or VSTT :-).  I’m making the source available under MS-PL so you’re free to port it to your unit testing framework of choice.  You’ll find the port is trivial if your unit testing framework uses the familiar Assert methods.

“What about the Silverlight Unit Testing Framework?”

Don’t worry, I haven’t forgotten about Silverlight developers :-).  In fact Test.Assert() has been integrated into the Silverlight Unit Testing Framework and will ship with the next version.

“How does it work?”

Test.Assert() improves your Unit Testing Framework by giving it access to the same information your compiler has: the expression tree.  Test.Assert is similar to Linq to SQL.  It converts your assertion expression into data, analyzes it, and then invokes the appropriate Assert methods.

howitworks

Like Linq to SQL, Test.Assert() only supports a subset of the functionality provided by the underlying API.  For certain assertions, particularly those that don’t use operators, you will still need to use the Assert methods.

“Which Assert Methods are supported?”

Here’s a table that shows which expressions map to which Test.Assert methods.

Expression

NUnit

VSTT/Silverlight Unit Testing Framework

value == true Assert.IsTrue Assert.IsTrue
value == false Assert.IsFalse Assert.IsFalse
value == 2 Assert.AreEqual Assert.AreEqual
value != 2 Assert.AreNotEqual Assert.AreNotEqual
value == “Jim” Assert.AreSame Assert.AreSame
value != “John” Assert.AreNotSame Assert.AreNotSame
“Jim” is string Assert.IsInstanceOf Assert.IsInstanceOfType
!(“Jim” is string) Assert.IsNotInstanceOf Assert.IsNotInstanceOfType
value < 2 Assert.Less N/A
value <= 2 Assert.LessOrEqual N/A
value > 2 Assert.Greater N/A
value >= 2 Assert.GreaterOrEqual N/A
double.IsNaN(value) Assert.IsNaN N/A
string.IsNullOrEmpty(“Jim”) Assert.IsNullOrEmpty(“Jim”) N/A
!string.IsNullOrEmpty(“Jim”) Assert.IsNotNullOrEmpty(“Jim”) N/A

If Test.Assert doesn’t recognize any patterns in your expression it will fallback to the Assert.IsTrue method and pass it your entire expression.  Often this - in addition including the expression in the failure message - is adequate.  If you want to ensure a specific Assert method is used you can always call that method directly as you would have before.

“What about VB.NET support?”

The expression in the failure message is actually language agnostic and is the produced by calling the ToString() method of the System.Linq.Expressions.Expression object.  Sometimes it looks like VB.NET, sometimes it looks like C#.  There is no reason why you can’t use Test.Assert() in VB.NET.

“What about F# support?”

Although the F# compiler is not capable of converting code into Linq expression trees, F# does have it’s own expression tree format which can be produced using the quotations language syntax. 

let expressionTree = <@@ value = “” @@>

You can convert F# expression trees to Linq expression trees using the F# Power Pack available with the latest version of F#.  It should be trivial to write a wrapper method which does the conversion and forwards it to Test.Assert().

“Okay, okay.  Where can I get it?”

You can download the source project (MS-PL) here.  It includes the VSTT and NUnit versions.  Test.Assert() will be integrated into the next release of the Silverlight Unit Testing Framework.  Enjoy.

Sunday, May 24, 2009

Better WPF/Silverlight Development in F#: Attached Dependency Properties

A very common idiom in WPF/Silverlight is the attached property.  Attached properties are properties that only have meaning in certain contexts, usually in relation to another class.  Attached properties are everywhere in WPF/Silverlight.  Although they are widely useful they are most commonly used with layout panels.  By introducing the notion of attached properties the architects of WPF were able to avoid having to add every conceivable property for every conceivable layout panel to each control (Top, Left, Grid Column, Grid Row, Rotation, and so on).

Of course neither the CLR nor C# has any notion of attached properties.   Therefore attached properties are typically implemented using a pair of static set and get methods on the Layout class.  These static setter/getter methods use a static dictionary to link a control to its attached property value.  As an example the Canvas panel lays controls out in a Cartesian coordinate system and has a Left attached property and a Top attached property.  Specifying these properties on a control looks something like this in C#:

Canvas.SetLeft(myTextBox, 23.0); Canvas.SetTop(myTextBox,24.0); myCanvas.Children.Add(myTextBox);

This works but it isn't ideal.  For one thing attached properties are not discoverable because they do not show up in the control’s intellisense list. However the real issue though is that the code is too low-level, exposing the developer to the implementation of attached properties rather than simply letting them express their intent.

F# has the notion of extension properties.  Like extension methods in C#, extension properties can be defined on a class outside of the class definition.  So with the smallest dab of code...

type UIElement with member this.Left with get() = Canvas.GetLeft(this) and set(value) = Canvas.SetLeft(this, value) member this.Top with get() = Canvas.GetTop(this) and set(value) = Canvas.SetTop(this, value)

…I can do this…

myTextBox.Left <- 23.0 myTextBox.Top <- 24 myCanvas.Children.Add(myTextBox)

Much better.  Now the properties belong to the control but like extension methods they only appear when the assembly with Canvas is imported.  Unfortunately with the current build of F# you can't use attached properties in object expressions like this...

Image(Uri = Uri(“test.png”), Left = x * 20, Top = x * 40)

...however I've been assured by Don Syme himself that this will be fixed by VS 2010 Beta 2. 

So there you have it.  An admittedly small, but very nice trick.  More to follow.

.NET Language Evolution: Do you care?

Luca Bolognese recently announced that C# and VB.NET will now be co-evolved.  That is to say, no feature will be introduced to one without being added to the other.  I can't deny that this makes sense but as a language geek its certainly not very exciting news.  More ominously Luca hinted language evolution was going to "slow down."  Yikes.

ida_fossil_images

Apparently some of our customers are having difficulty ramping up on language features introduced alongside .NET 2.0.  Although I sympathize with these customers Microsoft made the right call when they took an aggressive approach towards language evolution, adding very significant new features inspired by functional languages.  Increasingly their customers are having to write scalable, asynchronous code to leverage multi-core processors.  These are hard problems and learning to think about them differently is essential to success.  There is a parallel here to the introduction of VB.NET and the phasing out of Visual Basic.

The news that C# and VB.NET evolution is going to taper off should not come as a surprise.  You can't keep adding features to a programming languages forever and it's especially hard when they have such a long heritage.  Under the circumstances Anders has done an admirable job.  Unfortunately there are certain functional algorithms that developers cannot, and will likely never be able to, express cleanly in either C# or VB.NET.

Enter F#.  Visual Studio 2010 Beta 1 is here and if you take the plunge you'll find that F# has finally been elevated to a first-class .NET language along-side C# and VB.NET.  We have every reason to believe F# will continue to evolve.  For starters it's just the first version.  Don Syme has also expressed interest in adding language features from Haskell as well.  The interesting question is: Does Language Evolution Matter?

There is some controversy over the importance of programming languages.  Some believe that it's primarily a developers knowledge of the existing class libraries that matters.  It's hard to deny this given the massive size of our libraries today.  However my personal experience is that in recent years learning the new language features introduced in C# has significantly improved my productivity, as well as the quality of my code.  It still fills me with such a sense of wonder that simply thinking about a problem differently can have such a profound effect.  It is for this reason that I've already made F# my primary language for play.  I hope to get the opportunity to use it at work at some point as well.  There are some very compelling reasons to use it to solve certain types of problems we face in WPF/Silverlight development. After all if not at Microsoft, then where? :-)

You can expect more Silverlight/WPF-related F# blog posts from me in the future.

Monday, April 27, 2009

Rx Framework: Asynchronous Programming Made Easy

A few weeks ago, to little fanfare Erik Meijer gave a presentation on the Rx Framework at the Lang.NET symposium.  You probably missed it.  Don't worry though.  It's no big deal.  It's only the culmination of one the most significant discoveries about the fundamental nature of asynchronous programming.  Oh yeah, and it's coming soon to the .NET Framework.

The Rx Framework uses Linq to build asynchronous code declaratively.  One of the perks of working at Microsoft is that I've been using it for months now.  Now that it has finally been talked about publicly I fully intend to start blogging about it but I'm waiting for the folks responsible, notably Wes Dyer, to take the plunge .  In the meantime here's a link to the presentation.  Watch it here while it's still on-line.

Thursday, April 16, 2009

An F# Solution to Eric Lippert's Challenge

David Anson recently brought Eric Lippert's challenge to my attention. I can't resist an opportunity to showcase F#'s strengths so I thought I'd throw my hat into the ring with a solution.

I'll briefly summarize the problem for those too lazy to follow the link :-):

Given a sequence of strings, concatenate them in a way similar to natural language.  For example the sequence "ABC", "DEF", "G", and "H" should be output as:

{ABC, DEF, G and H}

"ABC" and "DEF" should be output as...

{ABC and DEF}

...and finally an empty sequence should yield the following output:

{}

Of course this problem is simple enough to solve.  The real challenge is creating a solution which is declarative and efficient.  In order to achieve the desired result we must determine if each item is the first, the last, or is in the center without relying on random access. The typical approach in C# or VB.NET would be to get an enumerator from the sequence, step through it, and create a state machine that keeps track of the last two values.  Unfortunately this approach wouldn't scale and would be full of corner cases to handle. 

Let's see if we can do better with F#.

open System open System.Text let concat_string (list: string seq) = let tripleWise = Seq.append list [null] |> Seq.scan (fun (_, previousPrevious, previous) current -> (previousPrevious, previous, current) ) (null, null, null) let contents = tripleWise |> Seq.map (function | _, null, _ -> String.Empty | null, curr, null -> curr | null, first, _ -> first | _, last, null -> sprintf " and %s" last | prev, curr, next -> sprintf ", %s" curr) let builder = StringBuilder() contents |> Seq.iter (fun item -> (builder.Append(item) |> ignore)) sprintf "{%s}" (builder.ToString()) // prints "{ABC, DEF, G and H}" printf "%s" (concat_string ["ABC"; "DEF"; "G"; "H"]) // prints "{ABC and DEF}" printf "%s" (concat_string ["ABC"; "DEF"]) // prints "{ABC}" printf "%s" (concat_string ["ABC"]) // prints "{}" printf "%s" (concat_string [])

Let's take a look at the program step by step.

Type Inference, Whitespace Awareness, and Type Aliases

let concat_string (list: string seq) =

The first line of code contains the only type declaration in the entire program. Not too shabby.  For those that don't know "string seq" is a type alias for IEnumerable<string>.  Having a type alias for sequences is really nice because sequence processing is so common in both C# and F#.  Notice that like Python, F# is also whitespace aware.  These three features help F# achieve Python-like terseness without sacrificing performance or type safety.

Structural Types

My solution leverages F#'s native support for structural types, that is types that can be used to group arbitrary values together.  The following code creates a sequence of triples, which is a group of three values.  Notice that pattern matching is used to introduce descriptive identifiers for each element in the triple.

let tripleWise = Seq.append list [null] |> Seq.scan (fun (_, previousPrevious, previous) current -> (previousPrevious, previous, current) ) (null, null, null)

The "tripleWise" identifier refers to a sequence of triples containing the previous, the current, and the next item.  For example if the input list is defined as "ABC" and "DEF" then tripleWise will be:

(null,null,null), (null,null,"ABC"), (null,"ABC","DEF"), ("ABC","DEF",null)

The scan function works in a way very similar to System.Linq.Enumerable.Aggregate.  Here's a C# example that uses Aggregate to sum a sequence of numbers. 

new[]{2,4,4,2}.Aggregate((accumulatedValue, current) => accumulatedValue + current, 0)

The difference between scan and Aggregate is that scan returns the intermediary accumulated values as a sequence.  Given the example above scan would return a sequence of the following values:

0, 2, 6, 10, 12

An empty triple is used as the initial value and scan is passed a function which shifts each item in the sequence through the triple from the right to left. Each time it returns the resulting triple. Now we have a sequence of triples containing the previous, current, and next values.  For each triple we can determine if the middle item is the first item or the last item by checking whether the left or right items are null respectively.  Note that by appending null to the end of the original sequence in the first line we can be sure that the rightmost item in the last triple will be null.

Parallelizing the Code

We've successfully avoided state and mutation and we now have a sequence of snapshots of each value and its previous and next values.  This is very important.  Now we can process each triple in the sequence in any order we like: last to first, first to last, or first and last at the same time. 

let contents = tripleWise |> Seq.map (function | _, null, _ -> String.Empty | null, curr, null -> curr | null, first, _ -> first | _, last, null -> sprintf " and %s" last | prev, curr, next -> sprintf ", %s" curr)

The code above introduces a function that uses pattern matching to declaratively transform each possible triple into a string.  It just doesn't get much more readable than this.  This function is applied to each element using map (equivalent to System.Linq.Enumerable.Select) which yields a sequence of strings.

Just for fun let's see how much work it would take to parallelize the code above using Matthew Podwasaki's F# parallel extensions library and the latest CTP of the Parallel Extensions.

let contents = tripleWise.AsParallel() |> PSeq.map (function | _, null, _ -> String.Empty | null, curr, null -> curr | null, first, _ -> first | _, last, null -> sprintf " and %s" last | prev, curr, next -> sprintf ", %s" curr)

Notice that all I had to do was add 14 characters!  Now the code above should increase in speed at a linear rate with the number of cores on the processor.  Just try that with a state machine. :-) 

In the next five years its very possible we will see processors with over 50 cores on a desktop.  This is one of the reasons I get so frustrated when I see developers unnecessarily using state in their computations.  State is the new GOTO.  It should have to be justified.

State When it Makes Sense

Notice that at the end the strings are concatenated using a StringBuilder. 

let builder = StringBuilder() contents |> Seq.iter (fun item -> (builder.Append(item) |> ignore)) sprintf "{%s}" (builder.ToString())

This operation is decidedly impure.  This demonstrates another wonderful F# feature: the ability to perform stateful operations when it makes sense. It's important to understand there's nothing preventing us from writing C#-style imperative code in F#. 

An alternate, pure approach to the problem above would've involved using reduce (equivalent to System.Linq.Enumerable.Aggregate) to concatenate all the strings together using the + operator.  Although reduce, like map, can be parallelized it is unlikely that this would improve performance because concatenating strings creates so much extra work.  Each time two strings are concatenated a new one must be created and the contents of both strings must be copied to a new memory location.  Under the circumstances it makes sense to add a dash of state and use a StringBuilder.

Learn F#

The entire program is 25 lines including whitespace and imports and I'm very comfortable with its trade-offs.  I look forward to seeing what the other developers come up with but I'm confident that no one will do better in C#.  F# really shines when it comes to computation.  Learning it is a must if you consider yourself a sharp Elvis or an Einstein and you make your living with .NET.

About Me

My photo
I'm a software developer who started programming at age 16 and never saw any reason to stop. I'm working on the Presentation Platform Controls team at Microsoft. My primary interests are functional programming, and Rich Internet Applications.