Making Instant C# Viable – Part 1

At some point several weeks ago, I came across Bret Victor‘s presentation “Inventing on Principle”. In it, among many amazing prototypes, Bret demonstrates a little app in which he can write code and see the live running results next to the code (starts at 16:47).

Bret Victor – Inventing on Principle from CUSEC on Vimeo.

After seeing this little app, my first thought was simply that this was genius; the next was “I want this for C#”. Now, this idea demos really well and is fairly simple to prototype, but I find there’s a lot of problems you start running into when you try to make an actual tool out of it; so I started a research project currently called “Instant”. The plan is to blog about the evolution of the project as I work towards making something real out of it, including what problems I run into and how I solve them. This will serve as not only a running set of examples on using Roslyn, but hopefully an interesting exploration of the space. We’ll start by matching Bret Victor’s demo, and then take it from there (hopefully to a Visual Studio and MonoDevelop plugin). It’s worth noting that I have absolutely no experience with compilers, runtime internals, or any of that sort of thing that you might expect are necessary for this. As a result, everything is very much a work in progress.

Here’s a working prototype roughly matching Bret’s demo:


Get Adobe Flash player

In this demo you can see I implement binary search and I can see the results of the code execution on the right. When I change the search parameter I can instantly see that there’s a bug, so I fix the loop and see the new behavior immediately. So how did I do this?

The first thing we’ll need is a data structure of the code itself. I knew about Roslyn already, and while I realized the importance of the project, I never really personally had a need for it – until now. What I knew going in was that Roslyn was going to give me an object representation of the code. What I didn’t know is that they have a ScriptEngine class, and it rocks. My initial thought was that I would lift all the local variables from a single test method, run each statement one at a time through the script engine, and then read from the hosting class I’d created what the current variable states where. So I dug in and wrote a SyntaxRewriter that did the lifting for me, and then it occurred to me how much I was over-complicating things.

With the ScriptEngine class, you can execute code in the context of a Session. Session allows you the ability to supply a “host object”, which you initialize and then pass to the session. In the code of your “script”, you can call methods on this host object as if the code you’re running was just another method on the same class. This, combined with the ability to rewrite the class gives us a simple solution: Rewrite the code to include calls to methods that log the values. The solution that I felt covered the most scenarios on it’s own was to replace all assignments with a call to a logging method that returns the object.

Basically, turn:

int x = 5;

into:

int x = LogObject ("x", 5);

We’ll use two classes to get there, one to act as the rewriter, the other to act has the host object (or “logger”). The logger, as you might imagine, is quite simple:

public class Logger
{
	public string Log
	{
		get { return this.builder.ToString(); }
	}
 
	public T LogObject<T> (string name, T value)
	{
		this.builder.AppendLine (name + " = " + value);
		return value;
	}
 
	private StringBuilder builder = new StringBuilder();
}

Roslyn provides us with a SyntaxRewriter class that uses the visitor pattern to make it very simple to get up and running rewriting code. If you’ve ever used ExpressionVisitor implementing a LINQ provider, you should feel right at home. We’re given us two ways to construct new syntax: 1) Use static methods and pass in object representations of all of the elements making up the syntax or 2) Pass in a string representing just the piece of syntax we want and have Roslyn parse it for us. #1 is frankly a bit cumbersome currently, so we’ll go with #2.

So, for our previous example, we want to go from a variable name and value to a log call for them:

internal class LoggingRewriter
	: SyntaxRewriter
{
	private ExpressionSyntax GetLogExpression (string name, SyntaxNode value)
	{
		return GetLogExpression (name, value.ToString());
	}
 
	private ExpressionSyntax GetLogExpression (string name, string value)
	{
		return Syntax.ParseExpression ("LogObject (\"" + (name ?? "null") + "\", " + value + ")");
	}
}

Now we need to actually use it, so we’ll start with variable declarations (which are not the same as assignments):

protected override SyntaxNode VisitVariableDeclarator (VariableDeclaratorSyntax node)
{
	// We don't care about: int x;
	if (node.InitializerOpt == null)
		return base.VisitVariableDeclarator (node);
 
	EqualsValueClauseSyntax equals = node.InitializerOpt;
 
	// Get a log expression using the variable name and the value it's being assigned.
	ExpressionSyntax logExpression = GetLogExpression (node.Identifier.ValueText, equals.Value);
 
	// Update the immutable syntax object with value expression
	equals = equals.Update (equals.EqualsToken, logExpression);
 
	// Update the declaration with our new initialization expression
	return node.Update (node.Identifier, null, equals);
}

Now that we have a simple rewriter and our logger, let’s actually see it work. I’ll go ahead and assume you know how to set up a simple UI with two textboxes.

public class EditorViewModel
{
	public EditorViewModel()
	{
		// We need to set up our 'scripting' environment,
		// we'll specify assembly references and using
		// statements here for now
		this.scripting = new CommonScriptEngine (
			new [] { // References
				typeof(string).Assembly // mscorlib
				typeof(Logger).Assembly // our app
			},
			new[] { // Using statements
				"System"
			});
	}
 
	// ... UI stuff ... //
 
	private CommonScriptEngine scripting;
	private void ProcessInput()
	{
		var logger = new Logger();
 
		// Parse the code we've typed into a node that we can
		// manipulate
		SyntaxNode root = Syntax.ParseCompilationUnit (Input);
 
		var rewriter = new LoggingRewriter();
		// Here we hand our rewriter the node that we just
		// parsed and we'll get back the rewritten node.
		root = rewriter.Visit (root);
 
		try
		{
			// Create a new scripting session with the host
			// object that we created to log our state
			Session s = Session.Create (logger);
 
			// We hand the scripting engine our final code
			// to run and the scripting session to use.
			this.scripting.Execute (root.ToString(), s);
		}
		catch (CompilationErrorException cex)
		{
			// We'll ignore compilation errors, there'll be
			// plenty while you type. Outputting this, however,
			// is a great way to debug your syntax rewriter.
		}
		catch (Exception ex)
		{
			// We want to show any other errors, like those from
			// the code that you wrote.
			Output = ex.ToString();
			return;
		}
 
		// At this point we have something usable, show the output from
		// the logging host object.
		Output = logger.Log;
	}
}

And there we go, we can see any time we declare a new variable and what it’s value is. Now that we’ve got the infrastructure all set up, let’s go a little farther and handle all assignments. Assignments are binary expressions, they have a left (the variable) and a right (the value it’s being assigned to) side to them, so we’ll check each binary expression to see if it’s an assignment and rewrite it’s value appropriately:

protected override SyntaxNode VisitBinaryExpression (BinaryExpressionSyntax node)
{
	switch (node.Kind)
	{
		case SyntaxKind.AssignExpression:
 
			IdentifierNameSyntax identifierSyntax = (IdentifierNameSyntax) node.Left;
 
			// We just want the variable name
			string name = identifierSyntax.PlainName;
 
			// Get a logging expression for the value
			ExpressionSyntax logExpression = GetLogExpression (name, node.Right);
 
			// Update the node with our logging expression
			return node.Update (node.Left, node.OperatorToken, logExpression);
 
		default:
			return base.VisitBinaryExpression (node);
	}
}

Update (4/18): The above code has a bug! This works great for simple expressions like x = 5, but what about something more complex like

i < x = 5

In this case, the left side of the binary expression is:

i < x

Casting this as a name will obviously not work, so we need to do a search for the name. We’ll look at the right side of any binary expression we come across and return once we find an IdentifierName:

private IdentifierNameSyntax FindIdentifierName (ExpressionSyntax expression)
{
	// If we're at a name, we can just return it
	IdentifierNameSyntax name = expression as IdentifierNameSyntax;
	if (name != null)
		return name;
 
	// If we find a binary expression, look at the right side
	BinaryExpressionSyntax binaryExpression = expression as BinaryExpressionSyntax;
	if (binaryExpression != null)
		return FindIdentifierName (binaryExpression.Right);
 
	// If we don't know what to do, return null so we explode and we can find the bug ;)
	return null;
}

Now, we’ll replace a line in our previous code to use this:

IdentifierNameSyntax identifierSyntax = FindIdentifierName (node.Left);

And there we have logging simple assignments! In part two, we’ll expand upon this with more assignments and pre/postfix unary operators. Now, if you’d like to play with this now, install the Roslyn CTP and grab the prototype source from GitHub. Fair warning though, it’s changing rapidly and may not work at any given point.

Note: This post is based on the first Roslyn CTP, I intend to update it when a new version is released.

Avoiding callbacks to the UI thread with async and WinRT

You probably already know that async operates by using the SynchronizationContext of the call site to invoke its callback. This behavior is great and makes sense for the vast majority of scenarios. There are a few, however, that it is not ideal for and it centers mostly around library developers like myself. If you didn’t know this, you may want to go watch this fantastic talk that contains a deep dive of async: The zen of async: Best practices for best performance. In fact, if you are interested in async with .NET, I recommend you watch it regardless.

I write a lot of socket based software, so I started writing my own library to provide a consistent (and higher level) API across all platforms and naturally I want it to work on WinRT. One of the first things I looked into when I got my hands on the WinRT bits was the replacement Socket API, which contains several async methods. In Tempest, once you receive some data it constructs message objects from the data, performing hash checking and sometimes even decryption. This is not code I want to be running on the UI thread for every single message.

So, I started looking around for solutions. Most I came up with involved not using the async keyword, calling out to the ThreadPool from the continuation, or using an outside thread to initiate the call. The simplest and most efficient answer I could come up with is to just not use async, but I didn’t want to accept that. Both Task.ContinueWith and IAsyncInfo.Start() do not pay attention to the SynchronizationContext, that is a feature of await:

And, just as a reminder and proof:

The same demonstration could be done for using .ContinueWith() vs. await on a Task. What I thought was that I’d be relegated to using these for advanced purposes, until I watched the talk I linked above. There’s a new method on Task, called ConfigureAwait(bool) which enables you to ignore the SynchronizationContext. What about IAsyncInfo though? There is a StartAsTask extension method on it after all, so let’s see if that works:

As it turns out, it does. Unfortunately there’s one small difference for which I can only speculate as to the reason. When you use the Task  and disable the captured context, you end up on a ThreadPool thread. However, when you use the IAsyncOperation returned directly, you still end up on a different thread, but not a ThreadPool one. One possible logical explanation is that it’s actually using WinRT’s ThreadPool to execute:

We can see here that WinRT’s ThreadPool threads do not get identified by Thread.IsThreadPoolThread.

Getting back to the code, although still an improvement on using ContinueWith, it’s still quite long. Here’s a little extension method that combines the two by just adding an overload for StartAsTask to take the same argument as ConfigureAwait.

public static ConfiguredTaskAwaitable<T> StartAsTask<T> (
	this IAsyncOperation<T> self, bool continueOnContext)
{
	if (self == null)
		throw new ArgumentNullException("self");
 
	return self.StartAsTask()
		.ConfigureAwait (continueOnContext);
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
	await DeviceInformation.FindAllAsync().StartAsTask (false);
}

So we can see that it is possible to use async without dumping back to the UI thread for calls originating from the UI thread. In some scenarios it still may not be desirable, depending on what you’re doing and your desired performance. The async keyword introduces a non-trivial amount of extra code, so if you’re concerned with the performance, I once again recommend you watch this talk.

TL;DR: Use await IAsyncInfo.StartAsTask().ConfigureAwait(false);

Converting Tempest to run on WinRT: Part 1

First, a short introduction to Tempest. I had avoided posting about this project in the past because I wanted the first post to be a quick tutorial and announcement of a beta. However, this is a perfect opportunity to really dive into some of the lower level APIs of WinRT and share the experience.

Tempest is designed to be a simple application protocol messaging library that works everywhere. This is to say that it gives you a simple way to define messages and lets you select how these messages are transported. Furthermore, the library is built to work on .NET 3.5, .NET 4, Mono 2.10, Silverlight 4 and Windows Phone 7.? “Mango”. Though, at this point in time, I’d consider Tempest to be an early alpha for .NET and Mono. Silverlight and Windows Phone 7 support compiles, but assuredly does not work yet.

Getting it to compile

For Part 1 we’ll talk about even getting Tempest to compile. Keep in mind that the vast majority of the code must still work on standard .NET, so converting over to WinRT APIs completely isn’t an option. To support the various platforms, there’s a number of compiler defines already present in Tempest:

  • SAFE – Disables any unsafe optimizations (unsafe, System.Reflection.Emit)
  • NET_4 – Enables .NET 4 specific code. This is mostly optimizations from System.Collections.Concurrent and using SpinWait, but does include one very useful API based on Task.
  • SILVERLIGHT
  • WINDOWS_PHONE

WinRT does not contain System.Reflection.Emit, so first I turned SAFE on. Type.IsValueType, which is used primarily in MutableLookup`2 from Cadenza, has been moved to TypeInfo. For a quick fix, I replaced the check for it with:

if (default(TKey) == null)

Simple enough change, but the error list at this point is still quite daunting. Here’s a short list of what was affecting me:

Networking

As you might imagine, for a networking library, the first is a huge blow. As WinRT has its own implementation of sockets, I’ll have to write a new transport provider. Fortunately Tempest is designed to be able to do this, so for the moment I’ll just remove the existing network implementation altogether.

Unfortunately that wasn’t the only usages I had, as System.Net.EndPoint was used throughout my contracts for connection targets. So either I can write WinRT only implementations of EndPoint, or I can write my own type and take control. I opted to write my own types (prototype design): ConnectionTarget, DnsConnectionTarget, IPConnectionTarget.

Reflection

When I was working on this last night, I was under the impression that Type had simply been gutted. Today I know that many of the members I had been using were moved to TypeInfo. There is an extension method in System.Reflection on Type called GetTypeInfo() that will get you the TypeInfo instance. In order to facilitate code compatibility with normal .NET, I added my own little extension:

#if !WINRT
public static Type GetTypeInfo (this Type type)
{
	return type;
}
#endif

Using this, I can just call .GetTypeInfo() on my type instances in either framework and all should be well. It’s not terribly efficient as I can’t store instances to the proper type easily/cleanly most of the time, but it gets the ball rolling.

Despite TypeInfo containing most of what was originally on Type a few things are still missing, such as .GetMembers(). I was instead able to use TypeInfo.DeclaredProperties and its friends with LINQ to get to the members I wanted, including filtering I was originally doing in LINQ after GetMembers().

Serialization

To be perfectly honest, where most of the reflection used and all of .NET’s built in serialization is, is in a custom automatic serialization system. This is probably the buggiest and worst designed aspect of Tempest. Last night I made the decision that for WinRT (thinking at the time reflection was gutted), I’d only support Tempest’s ISerializable and ISerializer<T> interfaces. For now I’m going to leave that restriction in place until I can get it sorted out.

While System.Runtime.Serialization is present with DataContractAttribute and friends, SerializableAttribute and System.Runtime.Serialization.Formatters.* are not. These portions of code were optional and already disabled for Silverlight, so I just added the WINRT flag to the check.

Miscellaneous

The types using System.Buffer weren’t used anywhere except for the existing networking implementation, so I simply removed them from the WinRT build for now. Having gotten things to compile at this point, I decided to see what would happen if I turned on NET_4, and to my surprise everything compiled as is. It appears that WinRT’s support of the baser types (like collections) is quite good. Where things start talking to the OS (Sockets) is where things start to get replaced, and old crufty systems (SerializableAttribute) seem to have been trimmed out.

Now that I have the basic system compiling, I need to implement a transport using Windows.Networking.Sockets, which will be Part 2.

Using WinRT from .NET

As it turns out, it is possible to use the WinRT APIs from standard .NET. You’ll need the full Visual Studio 2011 preview installed on the Windows 8 Developer Preview.

First, create a new WPF project. Then, go to add references and press “browse”. Navigate to C:\Program Files (x86)\Windows Kits\8.0\Windows Metadata

C:\Program Files (x86)\Windows Kits\8.0\Windows Metadata

Make sure you select “All Files”. Note that VS11 gives you an error if you try to add more than one at a time, so you’ll have to add each individually. We’re going to show a quick app that lists devices, so we’ll need a couple of these namespaces: windows.foundation.winmd and windows.devices.enumeration.

First we’ll make a little view model:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Devices.Enumeration;
using Windows.Foundation;
 
namespace WpfApplication1
{
    public class MainWindowViewModel
        : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
 
        public MainWindowViewModel()
        {
            var operation = DeviceInformation.FindAllAsync();
            operation.Completed = CompletedFindDevices;
            operation.Start();
        }
 
        public IEnumerable<DeviceInformation> Devices
        {
            get { return this.devices; }
            private set
            {
                if (this.devices == value)
                    return;
 
                this.devices = value;
                OnPropertyChanged ("Devices");
            }
        }
 
        private IEnumerable<DeviceInformation> devices;
 
        private void OnPropertyChanged (string propertyName)
        {
            var changed = PropertyChanged;
            if (changed != null)
                changed (this, new PropertyChangedEventArgs (propertyName));
        }
 
        private void CompletedFindDevices (IAsyncOperation<DeviceInformationCollection> asyncInfo)
        {
            Devices = asyncInfo.GetResults();
        }
    }
}

And then the Xaml (don’t forget to hook up the datacontext to the view model in your code behind):

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <ListBox ItemsSource="{Binding Devices}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Name}" />
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Window>

And voila:

This doesn’t cover being able to implement the various platform contracts, but it’s a start.

Update: Apparently the opposite is true as well.. kind of. It’s possible to reference your existing .NET assemblies and use them in a WinRT application. It remains to be seen or heard whether that will be allowed for the App Store, but it does work in practice. The gotcha is that you can’t reference the missing pieces of the BCL, so if you need a type there (System.Net.EndPoint for example), you’re still out of luck.

Update 2: The app certification utility fails WinRT apps calling unsupported .NET APIs. So, they’ll run, but you won’t get them on the store.