Wednesday, June 20, 2007

posted on Wednesday, June 20, 2007 9:01:09 AM (Pacific Standard Time, UTC-08:00)  #    Comments [0]
 Wednesday, June 13, 2007

I was helping a friend with a problem recently.  He was taking a set of serial web service calls and doing them in parallel to save time, and was not up-to-speed on the best approach for that.  Once he settled on an approach, he realized that since his web service calls were being wrapped in an abstraction layer, he didn't have the Begin/End asynchronous call methods that are provided by the proxy class.

"No problem, just wrap them in a delegate".  The compiler automatically gives you Begin/EndInvoke methods in addition to the synchronous Invoke method.  And, you're guaranteed not to mess up the implementation because it's all provided by the CLR!  Just one of those things you might forget if you find yourself in the same situation.

posted on Wednesday, June 13, 2007 3:37:55 PM (Pacific Standard Time, UTC-08:00)  #    Comments [2]
 Wednesday, May 23, 2007

Wouldn't that be a great band name?  Evidently, while Jenna was eating lunch today, our cats were nearby, and she wanted to give them high fives and share her oranges with them.  During which, she was heard to exclaim, "High five, kitties".

She's progressing amazingly.  She's been talking enough to have conversations for several months now.  Last night, instead of me reading to her, she read to me.  Of course, she merely turned pages and on each page would say some words that I say when I read that particular page.  She would also point at the pictures and say what things are.  What was really interesting is that she did this with 2 books in parallel.  Rather than read them one after the other, she would read a page or 2 from one book, then switch to the other, which made for a very interesting story, considering that both books were about rabbits going to bed (Goodnight Moon and Guess how much I love you).

Tomorrow, my mom and dad are visiting for the first time since we moved.  We're pretty excited about the fun that will be had.  Hopefully, Jenna will be over her double ear infection/sinus infection that we didn't know she had. (her only symptom was some coughing)

posted on Wednesday, May 23, 2007 11:03:53 AM (Pacific Standard Time, UTC-08:00)  #    Comments [1]
 Thursday, May 17, 2007

After my last few CLR posts, I've had a couple of private inquiries regarding the usefulness of closed static delegates.  To bring everyone up to speed, a delegate pointing to an instance method needs a "target" instance to operate on (we'll get to open instance delegates later).  A static method, needs no such target, so we can leverage the "space" used for the instance case to carry around another object of interest.  We call a delegate with a provided value for this space "closed over the first argument".

For example, let's say we have a static method that does some operation on two numbers.  For simplicity, let's just say it adds them.  Our silly class and method might look like this:

public static class NumberFunctions {
   public static double Add(double first, double second) {
      return first + second;
   }
}

Normally, a delegate for this method would look like:

public delegate double BinaryOperation(double first, double second);

But, we're going to create a closed static delegate, which means we're going to "burn" the first argument into the delegate itself, so it's not needed in the delegate signature.  Instead, we'll use the following delegate signature (I didn't spend much time thinking up these names, I hope they make sense:

public delegate double ClosedCall(double other);

So, how do we create the delegate?  Normally, since C# (pre-Orcas) doesn't have syntax for creating closed static delegates, you are forced to use one of the Delegate.CreateDelegate overloads:

ClosedCall addToOne = (ClosedCall)Delegate.CreateDelegate(
        typeof(ClosedCall),
        1.0,
        typeof(NumberFunctions).GetMethod("Add", BindingFlags.Public | BindingFlags.Static));

Of course, we just spent 2 entries looking at a helper that can do this for us (I'm not claiming this is better, I just want you to be able to see what's happening):

ClosedCall addToOne = DelegateBinder.Bind<ClosedCall>(1.0,
        typeof(NumberFunctions).GetMethod("Add", BindingFlags.Public | BindingFlags.Static));

Now, a call to addToOne(someNumber) will yield the result of adding the supplied argument to one.  This is a contrived example, but you could imagine taking a method (perhaps generated on the fly via LCG), and "attaching" an instance to it via the first argument.  Then, being able to call it many times with different subsequent arguments, or passing it to another component that would provide the rest of the arguments.  In this way, you get the benefits of not having to keep track of an instance, without having to own the API for the instance.  Additionally, you could "chain" delegates together so that many arguments are captured in a stack of delegate calls, allowing closure-type semantics at the cost of some stack space (although since C# has closure support, you'd never really need to do that).

What's really cool is that with C# 3.0's Extension Methods feature, we now have language support for creating early-bound closed-static delegates.  If you bind a delegate to an extension method (using the regular syntax for an instance method), you will get the exact IL for creating an early-bound closed static method without our fancy helper class.  Let's see how that would look.  Let's use a different example to keep us on our toes.  Here's a helper function that creates email addresses:

public static class StringExtensions {
   public static string MakeEmailAddressWithAlias(this string domain, string alias) {
      return string.Format("{0}@{1}", alias, domain);
   }
}

Notice the "this" in front of the first parameter, this tells the compiler that the method should be considered when resolving method calls for string.  We'll use one of the delegate types provided in Orcas. Now, here's how the bind looks:

string fooDotCom = "foo.com";
Func<string, string> makeFooDotComAddress = fooDotCom.MakeEmailAddressWithAlias;

string email = makeFooDotComAddress("bar");

So, the result is that email will be bar@foo.com.

Hopefully, through these contrived examples, you can see the scenarios that closed static methods provide, as well as learn how you can create one the easy way with extension methods in Orcas.

posted on Thursday, May 17, 2007 9:46:22 AM (Pacific Standard Time, UTC-08:00)  #    Comments [0]
 Monday, May 14, 2007

In my last post, I showed a nifty way of constructing "early-bound" delegates using LCG.  Here's the same helper class implemented without LCG:

public static class DelegateBinder {
	public static TDelegate Bind<TDelegate>(object firstArg, MethodInfo method) {
		return (TDelegate)Activator.CreateInstance(
			typeof(TDelegate),
			firstArg,
			method.MethodHandle.GetFunctionPointer());
	}
} 

This one is quite a bit simpler, and extrapolating from what we learned last time, it's easy to see what's happening.  Hopefully, you are already familiar with the Activator class.  Basically, this just shows the managed call chain that produces a function pointer to a method given a MethodInfo.

I really like the LCG-based implementation, but only because of my love of DynamicMethod.  It's pretty complex, and aside from opportunities for caching, doesn't really have anything over this implementation. This one is just plain simple, and would have a single-line implementation if I hadn't put some line breaks to avoid formatting problems.  It does, however, highlight the annoyingness of having to work around the compilers' "helpfulness" when it comes to delegate construction.  If only I could just call the constructor directly.

It is worth noting that this doesn't work in the Silverlight 1.1 alpha or the compact framework (or XNA for that matter), neither of which expose RuntimeMethodHandle.GetFunctionPointer().

posted on Monday, May 14, 2007 3:40:01 PM (Pacific Standard Time, UTC-08:00)  #    Comments [2]
 Friday, May 11, 2007

In a previous post about delegates, I discussed the following interesting cases of delegates:

  • Closed static
  • Open instance

See the previous post for the full explanation, but these basically open up some interesting dynamic scenarios.  The problem is that C# and VB do not expose syntax for constructing these in an "early-bound" fashion, that is using the special constructor on the delegate type rather than Delegate.CreateDelegate (which more or less binds via reflection).

For most scenarios this is not a huge problem, but there are some performance considerations and other issues to consider that I don't really want to dig into at the moment.  One sufficiently important scenario is testing early-bound invocation.  If your language doesn't support something, how can you test it?  Well, you can write the whole test in IL, but that is not a terribly maintainable proposition.

Another option is to only write the part you need in IL.  Unfortunately, C# doesn't allow you to write inline IL, but you can use Reflection.Emit.  And, since v2.0, you can use LCG (Lightweight Code Generation) via DynamicMethod.

The trick here is to understand how delegates are instantiated.  Delegates are just classes like any other.  They inherit from MulticastDelegate (typically).  The special part is that the runtime provides all the implementation and they have a special constructor.  Here's (approximately) the constructor signature for System.Action<T>:

public Action(object o, IntPtr method)

Object? IntPtr?  What the heck? Well, it's not as bizarre as you might think.  The object is simply the first argument for the invocation.  This allows binding to a particular instance ("this" for instance methods, arg 0 for static methods). The IntPtr is a pointer to the method.  "Pointers?!!?!?! in managed code?!?!" you say?  That's right, a pointer.  An object is easy enough to come by, but where do I get the pointer?  Well, the pointer can be easily retrieved via the ldftn opcode.  It loads the address of a given method (described via a token in IL, and a MethodInfo in Reflection.Emit).

Lets cut to the chase.  Here's a little class that can bind a method to a delegate type and allow you to provide the first argument (you'll need System, System.Reflection, System.Reflection.Emit using statements):

public static class DelegateBinder {

    public delegate TDelegate Binder<TDelegate>(object firstArg);

    public static TDelegate Bind<TDelegate>(object firstArg, MethodInfo method) {
        DynamicMethod dynMethod = new DynamicMethod("PassthroughBinderImplementation", typeof(TDelegate), new Type[] { typeof(object) }, typeof(DelegateBinder));
        ILGenerator gen = dynMethod.GetILGenerator();
        //load the first argument
        gen.Emit(OpCodes.Ldarg_0);
        //load the address of the method
        gen.Emit(OpCodes.Ldftn, method);
        //create the delegate
        gen.Emit(OpCodes.Newobj, typeof(TDelegate).GetConstructor(new Type[] { typeof(object), typeof(IntPtr) }));
        gen.Emit(OpCodes.Ret);
        return ((Binder<TDelegate>)dynMethod.CreateDelegate(typeof(Binder<TDelegate>)))(firstArg);
    }
}

With this class, you can dynamically construct all the early-bound variants (ignoring variants for signature relaxation) like so:

using System;
using System.Reflection;
using System.Reflection.Emit;

public delegate string Passthrough(string str);
public delegate string BoundPassthrough();
public delegate string ProgramPassthrough(Program p);

public class Program {
    static void Main(string[] args) {
        Console.WriteLine("Open Static:");
        Passthrough ospt = DelegateBinder.Bind<Passthrough>(null, typeof(Program).GetMethod("StaticImplementation", new Type[] { typeof(string) }));
        Console.WriteLine(ospt("Hello World"));

        Console.WriteLine("Closed static:");
        BoundPassthrough cspt = DelegateBinder.Bind<BoundPassthrough>("Hello World", typeof(Program).GetMethod("StaticImplementation", new Type[] { typeof(string) }));
        Console.WriteLine(cspt());

        Console.WriteLine("Open Instance:");
        ProgramPassthrough oipt = DelegateBinder.Bind<ProgramPassthrough>(null, typeof(Program).GetMethod("InstanceImplementation", Type.EmptyTypes));
        Console.WriteLine(oipt(new Program("Hello World")));

        Console.WriteLine("Closed Instance:");
        BoundPassthrough cipt = DelegateBinder.Bind<BoundPassthrough>(new Program("Hello World"), typeof(Program).GetMethod("InstanceImplementation", Type.EmptyTypes));
        Console.WriteLine(cipt());
    }

    public static string StaticImplementation(string str) {
        return str;
    }

    public Program(string payload) {
        _Payload = payload;
    }

    string _Payload;

    public string InstanceImplementation() {
        return _Payload;
    }
}

So, there are certainly cases that will break this, most involving incompatible signature issues between the method, delegate, and the first argument.  But I didn't want to make things more complicated for an example. Besides, the point of this is not really to give you some neat tool (you'll probably never need to do this), but to give people a better idea what the compiler is doing for you when you create a delegate.

posted on Friday, May 11, 2007 2:54:23 PM (Pacific Standard Time, UTC-08:00)  #    Comments [1]
 Thursday, May 10, 2007

One of my most successful comedic performances has got to be my rip-off of Dana Carvey's Grumpy Old Man character from SNL.  It was fun to pretend to be old.

Last night, I really felt old.  I was overseeing the youth as they played a variant of hide and seek, and I realized that there was something going on that I had never experienced.  The youth were using their cell phones to call each other and brag about their hiding places and trash-talking with the seekers about how they were never going to find them and such.  It was so interesting.  When I played hide and seek as a kid, not even our parents had cell phones!  Now everyone has them.  It was just a bizarre revelation.

posted on Thursday, May 10, 2007 8:59:57 AM (Pacific Standard Time, UTC-08:00)  #    Comments [7]
 Monday, April 30, 2007

Today is the MIX07 keynote (watch it live right now).  Scott Guthrie is currently on-stage spilling the beans about what's been going on here.  He just announced that Silverlight (v1.1) includes a cross-platform (Mac/PC at the moment) version of the CLR and the .net framework. I'll be talking about this alot in the coming months.  It's incredibly exciting stuff.

The NetFlix guys are on-stage showing off a demo of their new over-the-web movie viewing experience.  I hadn't seen this demo before. Very cool.

Scott just did his chess demo where the CLR engine plays chess against the IE javascript engine.  Very funny.

Scott just demoed cross-platform debugging (Running a Silverlight program on the Mac and hitting a breakpoint inside VS running on a PC).  Fantastic.

Scott's doing his airline demo.  I love this one because he starts with a cheesy "Hello World" app, and ends up with a fully-functional airline flight schedule viewer with crazy animations of planes flying around.

Scott just announced open source Ruby for .NET (IronRuby).  He's developing a Silverlight app with Ruby on the Mac with standard Mac tools.  Good job, John.  Now he's showing the dynamic language console, that gives you an interactive REPL console with Intellisense that can use any of the dynamic languages, or even mix the languages together on the fly.  All in the browser.  Freaking awesome.  I think alot of people missed the announcement about the DLR (dynamic language runtime) that anyone can use to build a dynamic language on top of .Net.

Wow, I've seen the MLB demo, but I hadn't seen the version running on the mobile phone!

posted on Monday, April 30, 2007 9:07:59 AM (Pacific Standard Time, UTC-08:00)  #    Comments [2]