Tuesday, February 27, 2007

I saw the following web address on a flyer in the breakroom: www.tacomaopera.com.  My brain didn't split it up as "Tacoma Opera", it read it as "Taco Maopera".  Rats, and I was thinking it was another Mexican food place to check off as being not good.

posted on Tuesday, February 27, 2007 3:32:26 PM (Pacific Standard Time, UTC-08:00)  #    Comments [1]
 Wednesday, February 21, 2007

A quickie here. I had written some code in javascript to simplify testing of a fairly dense, multi-dimensional feature area.  I could define the dimensions I wanted to test declaratively in a more or less JSON fashion and then bang them together via some enumerable-like extensions that I had written.  Viola, full test matrix implemented.

Unfortunately, I learned that I would be unable to take a dependency on the scripting host at run-time.  Too bad I had already invested the time in the solution, and I would now have to code the matrix myself.  But wait, this is a dynamic language I'm dealing with!  So, in a short time, I did some object substitution, and now my javascript is a precompiler that emits C# and other support files that I then compile to do the same thing.

Nikhil has a more general tool that goes the other way.  It compiles C# into javascript for use in AJAX apps.  While this is a handy way for people unfamiliar with the power of dynamic languages to jump into the AJAX world, I'm wondering if it's really a good idea in the long term.  On the one hand, reducing the number of language dependencies in a project is good for maintainability, but choosing the less-flexible one seems like the wrong choice.  Of course javascript has no formal set of class libraries, so that's a limitation.  Hmmm.  I'll have to think about this some more.

posted on Wednesday, February 21, 2007 10:05:09 AM (Pacific Standard Time, UTC-08:00)  #    Comments [0]
 Tuesday, February 20, 2007

All .NET developers, proceed immediately to Lutz Roeder's site (remember, I have his office shelves) and download Reflector 5.0.  It has a ton of new features.  So many that I won't attempt to list them here.

This tool was a part of my programmer's arsenal before I came to MS, and I still use it daily to spelunk around the managed code in the CLR and framework, even though I have access to the source code. It is an incredibly powerful tool that combines static analysis, documentation, disassembly (into multiple languages), search, etc.

If you're looking to get into C# for the first time (and I know several of you are), it is helpful to be able to look at your code as if it has been written in C#, or look at code that was written in C# in another language so you can see how C#'s constructs are saving you time (over some languages).

Ok, I said I wasn't going to list features, but I know some of you won't click through the powerpoint deck.  The new version can fold anonymous delegates, and even C# 3.0 lambdas and LINQ queries back into their original syntax.  Of course it's configurable, so you can still see what the compiler's doing for you.  It also adds proper Vista support.  It also adds support for code:// urls (Ex. code://mscorlib/System.Object). Oh, and the Add-Ins are hosted on CodePlex now.  Tons more stuff.  Get it now. No excuses.

posted on Tuesday, February 20, 2007 8:39:40 AM (Pacific Standard Time, UTC-08:00)  #    Comments [0]
 Monday, February 19, 2007

I'll take a break from the technical posts for a moment.  Friday night, I helped out with a youth lock-in up at the church.  It was just like old times (except no spitting ice down the stairs).

The youth group at our church is decidedly smaller than at our church in Austin.  But, it makes sense because the actual church is much smaller than our church in Austin.  There were about 8 guys there (the girls were elsewhere).  We pretty much played video games all night.  We had 2 Wii's, a PS2, an XBox and an XBox360.  We also played some (outdoor) capture the flag.  It was a variant that I hadn't played before in Texas, and I didn't really understand it.

The highlight of the night was linking the xbox and the 360 and playing some 4 vs. 4 Halo 2.  I don't like to brag, but I did pretty well.  Mainly it was fun because they were trash-talking pretty bad about how they were going to beat me.  One game in particular (4v4 Team Slayer on Beaver Creek) I lead my team to victory with 35 kills and only 3 deaths.

It was cool to connect with the guys in that way. They are having a "ski day" on Wednesday, and I'm bummed that I have to work.  The whole concept of a day trip for snow skiing is completely foreign and bizarre to me.

posted on Monday, February 19, 2007 11:43:11 AM (Pacific Standard Time, UTC-08:00)  #    Comments [3]
 Friday, February 16, 2007

So, my last post talked about delegates.  In it, I mentioned some compiler trickery involved in declaring events, but I didn't bother explaining it.  After reading it over again, and getting some feedback, I felt bad about glossing over what is pretty much the mainline scenario for delegates. So, what is an event?

An event is kind of like a broadcast. It enables an object to notifiy subscribers when some "event" occurs, give them relevant information about the event, and allow them to do something in response.  And, you guessed it, delegates are at the core of making this work.

Fundamentally, events are a callback mechanism, and could be implemented without delegates using anything from raw function pointers to interfaces, and the CLR doesn't keep you from doing either of those, but there's value in a consistent pattern.  In fact, the designers of the CLR felt so strongly about the value of this particular pattern, that it is part of the CLI spec (along with properties, another pattern that is implemented by other more fundamental constructs).

So, how do you make an event?  Well, in C#, you declare an event like you would declare a field whose type is some delegate and you add the "event" keyword.  So, somewhere in a type, you would have something like:

public event EventHandler Click;

Whether or not it's public depends on how you expect the event to be used.  EventHandler is a delegate with the following signature:

void EventHandler(object sender, EventArgs e);

This signature is another pattern that I'll talk about later.  For now, lets look at what the compiler does for our event declaration.  The compiler gives 3 things (if you don't count the things it already did for the delegate EventHandler):

  • A private field whose type is the delegate EventHandler
  • A (public in this case) method "accessor" for adding delegate callbacks: add_Click //Click comes from the event name
  • A (public in this case) method "accessor" for removing delegate callbacks: remove_Click

When other code wants to hook up to your event, they use the += operator on your event.  This is really syntax sugar for calling the add_Click method.  And, conversely the -= operator calls the remove accessor.

Interestingly, you can write your own implementation for the event pattern.  You might want to do this to save size in a possibly large tree structure with lots of events at each node.  ASP.net does this with controls.  Rather than every Control having tons of fields for each event, it has a sparse dictionary of event delegates, that is only populated for events that have "subscribers".  With a tree that can easily have thousands of controls per page view, this results in a sizeable savings.  How do you do this?  Well, in C#, you use the little known syntax:

public event EventHandler Click {

add {/* do something with value in here */}

remove {/* do something with value in here */}

}

Looks like a property eh? This causes the compiler not to create the 3 things I mentioned above. Instead, it calls your add and remove accesors to do the adding and removing (via the value keyword just like properties).  In it, you can do anything you want, although it's advisable to keep the same semantics as the default implementations.

So, lets talk a little bit about what happens when an event happens and it is called.  Let's say that several other classes have registered for your event (via the += syntax or whatever the compiler supports).  Inside your class, you simply call the delegate (there's a recommended pattern for this as well).  But wait, there's more than 1 subscriber!  Remember, delegates aren't just function pointers, and they are more powerful than using interfaces alone.  If you'll recall in the last post, I said that when you create a delegate, you're really getting a MulticastDelegate, which tracks an invocation list of delegates to run. (this is why the standard event pattern returns void, otherwise, you've got the weird situation of multiple return values from what appears to be a single call).  Under normal circumstances, each delegate in the invocation list is called and execution resumes.

posted on Friday, February 16, 2007 10:36:02 AM (Pacific Standard Time, UTC-08:00)  #    Comments [0]
 Thursday, February 15, 2007

Soon, my ownership area will extend to include delegates.  Since I'm fairly excited about this, I thought I'd celebrate by writing a little something about them.  So, what are delegates?  A casual observer might be tempted to write off delegates as a sort of managed function pointer.  While this comparison is certainly accurate, there's much more to explaining the power of delegates.

In general, delegates are a sort of universal method dispatch mechanism.  Initially, the scenario they supported was callbacks.  Delegates are one of the things that distinguish the CLR from other VMs like Java.  Java requires the use of interfaces to implement callbacks. (I'm only calling that out as a distinction, not saying the Java way is bad. although personally I like what delegates bring to the table)  So, delegates let you wrap up a method as an object to pass around, with the expectation that it will be called from another context.

Its sort of hard to talk about delegates because the discussion is often framed by the language that's exposing them.  Currently, no managed language exposes them in the way that they are represented in IL.  In C# and VB, you declare a delegate by simply defining a method signature.  From an IL perspective, the compilers generate a class that inherits from MulticastDelegate (another story I'll get to later), with an Invoke method that matches your signature, and some various constructors to support different things.  (You also usually get the corresponding asynchronous calling pattern support methods, but I don't want to get into that)  Some other delegate-related compiler trickery is involved in declaring events, which I'll cover later.

Under the covers, a delegate [conceptually] contains 2 things:

  • A target object
  • A target method

Now, generally speaking, the target method is the method to be run, and the target object is the object on which the target method will be run, but there are cases where this line is blurred a bit.  For instance, when a delegate is pointing to a static method, the target object is conceptually null (internally it's not, but that's an implementation detail).  I'll get into the other cases later.

So now you're saying, "Yup, that's a delegate.  Big deal.  What's so cool about that?"  What's cool about that, my friend is that delegates are the things that power virtually all of the coolest new language features that came out in v2.0 and will be coming out, including all the dynamic language goodness like IronPython.  It's the dynamic stuff that is really exciting, so let's talk about how delegates enable dynamic languages on top of a statically typed system.

(To be fair, Jim Hugunin did his initial Iron Python work before these features were available, but they now play a big role)  One of the pieces of work done in v2.0 was called delegate relaxation.  Previously, the target method had to match the delegate signature exactly.  Now, as you might expect intuitively, the signature can be relaxed such that the target method can have "more general" parameters and return something "more specific" than the delegate's signature.  This is typically defined in terms of covariance and contravariance, terms that even people who understand them get confused.  Here's the way I usually remember it: If I could wrap the target method with a method having the delegate's signature without casting, it will work. Anyway, this feature makes delegates quite a bit more flexible.

Before I go into the other features, lets talk a little about implementation. In normal method calling in the CLR, the first parameter becomes the "this" object.  (Which is why you see ldarg.0 in IL to put it on the stack.)  So, conceptually, the target object represents the first argument for the method. (There is an implementation detail that allows static methods to be called using the same convention, which is a really elegant solution) So, by extending this idea of the target object simply being the first argument, we get a couple of interesting variants.

The first is what is called "closed" static delegates.  This allows you to specify the first argument of a static method at delegate creation rather than at the callsite.  Notice this maps quite nicely to the dynamic language concept of adding a method to an existing instance of an object.  The language runtime just needs to be able to track these extra methods as part of its method dispatch logic.

The second feature is "open" instance delegates.  This allows you to create a delegate that points to an instance method, but doesn't define the target object.  Instead, the delegate signature can have an extra first argument that will specify the target object at the callsite.  When used with LCG (DynamicMethod), this can be used to implement things like adding a method to an existing type.  Again, the language runtime merely needs to add the logic to method dispatch.

These 2 features are intriguing to me because they are not directly exposed from VB or C#.  I believe VB9 exposes these, but they are not accessible in an early bound way in C#.  You can, however, create them via Delegate.CreateDelegate() using reflection, or use Reflection.Emit to generate the corresponding IL.

Hopefully, I'll have some time in the future to do some samples of these as well as discuss more about how these improve the dynamic language support in the CLR.

posted on Thursday, February 15, 2007 2:32:53 PM (Pacific Standard Time, UTC-08:00)  #    Comments [1]
 Monday, January 29, 2007

I dealt with several situations in the past months where the crux of the problem was confusion over assemblyname and filename.  Let's define what we're talking about:

  • Filename - The name of a file in the filesystem, such as System.dll
  • Assemblyname - The name given to an assembly to establish its identity.  In this case, we'll only concern ourselves with the "simple" name. such as System

Usually, any confusion that arises between the two can be resolved by reminding people that a filesystem is just one of the places you can get an assembly from.  For instance there are APIs for getting assemblies from byte arrays.

For those that still do see it... In the managed world, the assemblyname gives identity to the code that resides in the assembly.  If you have 2 assemblies with the same assemblyname, you expect them to represent the same identity (perhaps different versions, build flavors, bitness, etc.).  If we relied on the filesystem name, the identity of the code could change just by changing the filename.  That's not the semantics we expect.

So, why does the filename matter?  Why do we recommend keeping them the same?  Some of the reasons are simple convenience.  It's nice to look at a file and know what it is without cracking it open.  If the names are different, it's like me going to a party and wearing a nametag that says, "Peter".  While there is nothing keeping me from doing it, it causes confusion.  However, another more important reason to keep them the same is that assemblies are rarely loaded by filename.  References and most dynamic loads are done by assemblyname.  You don't take a reference to System.dll, you take a reference to System.  At some point, the loader has to find an appropriate file to load to satisfy that reference.  If System's filename is Peter.dll, then it's going to have a difficult time finding it to load.  This is actually the very reason that gacutil will not let you install an assembly into the global assembly cache if the filename doesn't match the assemblyname.  However, I think it's silly that it doesn't just fix the name for you.

What about multi-module assemblies?  Well, it's the module with the assembly manifest that matters.  It's the one that should match.  Then the rest of the files need to match the assembly manifest :). But, if you're using multi-module assemblies, let me know.  I'd like to know why.

posted on Monday, January 29, 2007 12:46:56 PM (Pacific Standard Time, UTC-08:00)  #    Comments [1]
 Thursday, January 25, 2007

Yup, it's that time again.  Today is my birthday.  I was lucky enough to get a Wii, which has been quite enjoyable.  Now I just need to get the component cables so I can stand to look at it. :)

posted on Thursday, January 25, 2007 9:05:54 AM (Pacific Standard Time, UTC-08:00)  #    Comments [2]