Friday, June 11, 2004

Since yesterday I have been thinking about NDAs. Yesterday I wrote the entry below about Monad and Pooja wrote hers, and I have been thinking.

 

The reason is this – MVPs before being awarded the title have to sign an NDA that says that certain information that Microsoft may reveal to them may not be publicly disclosed. The NDA is one in good spirit where employee of Microsoft who are part of product teams and doing such other core work may freely interact with MVPs about future products and ideas that are still being tested and such. A lot of MVPs actually give direct feed back to the product teams which reflect on the products that you see tomorrow.

 

The MVP program by its very nature is an award program and the winner of the title doesn’t directly commit anything to Microsoft. So a lot of the feed back from MVPs is neutral and critical in a very constructive sort of way, because MVPs really love their technology.

 

The problem with the NDA is simply that of late most MVPs (at least in the India circuit) don’t have a clear way of saying what is under NDA. We actually get to hear SO much about so many things happening that we are really not sure. So breaches of the NDA do happen simply one did not know that an item is under the NDA.

 

One thing that we were told of is that when in doubt – check with your MVP lead. That happens, but sometimes that is not very feasible. Sometimes you don’t even think of checking about something. Which is when another ‘rule of thumb’ was proposed at the India advocates day, 2004. At IAD it seemed ‘common-sense’ that what ever we can find on the web already is simply not under NDA – if we know something and it is not on the web yet (duh?) then it is under NDA.

 

This makes things a little tricky. Like when writing about Monad, I realize that a lot of information is actually available on the web – admittedly in bits and pieces, but still there. Now that I have access to the stuff as part of the beta program, can I write about it or not? We had a discussion last night with the India MVP lead and the ex India MVP lead and some of the Bangalore MVPs and to my surprise I was hearing that none of the stuff from the beta place could actually be disclosed. Also the above ‘rule of thumb’ stands corrected to ‘anything found on the Microsoft site is not under NDA’. !

 

Now that has some obvious contradictions – how for example do I know that I am talking about confidential information when the information is publicly available in some form? If there is a document that marks it as confidential but I do not have access to the document, does that make me in violation of the NDA? If I do have access to the confidential document, then what happens to conclusions I can draw from public information that is not explicitly stated elsewhere (though deducible) but is present in the document?

 

Some of this got me thinking today morning at the hacker Knight Lightning’s trial a decade back. Knight Lightning was brought to trial by the US secret service for stealing a confidential AT&T technical document that was estimated at 70k dollars or more (forgive my fading memory). The document was the centre of the debate there and in some sense was treated by the prosecution as being too sensitive to show even during the trial. The then newly formed Electronic Frontier Foundation under John Perry Barlow and Mitch Kapor came to Knight Lightning’s aid in the defense. It turned out that the document hardly discussed technical details of a sensitive nature. The cost of the document was a grossly over exaggerated figure, piled up as sheer administrative over head costs (things like the cost of the computer system used to typeset the document were added as the cost of the document). And as a final blow to the case it turned out that AT&T was actually selling documents of a similar but more technically detailed nature for hobbyists and enthusiasts to use (for about 13 dollars?) – which neither the prosecutors nor Knight Lightning knew about.

 

The issue about information being confidential while still being available in some form publicly is a very tricky one.

 

My own first exposure to the term ‘NDA’ was when I heard the recording of a speech by Richard M Stallman (founder of the Free Software Foundation) at Slovenia. RMS was talking about how an NDA imposed by Xerox for the printer driver software hurt the guys at MIT who were trying to fix a faulty laser printer that kept getting jammed. Stallman’s message was that NDAs “do have victims”. He did make several valid points and after listening to RMS several times I was sensitized to the issue of NDAs. So admittedly when I signed my first NDA with the company where I work, I did so after reading the document over several times and did it with shaky hands.

 

The issue about writing about Moand itself is a simple one – I had dropped a mail to the one of the contacts on the Monad team and I got prompt response. A few clarifications are left, but it seems to me that everything is in good faith now. In the case of Monad itself it is not an issue, especially when most of the folk at MS are so approachable and prompt when it comes to an relevant issue. The MVP crowd and the people around the MVP program are also were receptive and quick to respond about any queries.

 

However the general issue about NDAs itself is a relevant and could because serious issues really quickly, if communication between parties is not as transparent as in cases like mine.

 

Add to that I heard this rather recently – you cant reveal that you are under NDA? What? There is a lot I don’t understand. The thing about systems programming is that opinions are fact clearly distinguish each other – at least they are only a compilation away. Matters like this….  :-)

Friday, June 11, 2004 2:06:28 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Thursday, June 10, 2004

For a little less than a week now, I have been playing with the March build of the new command shell that Microsoft will be releasing in the Longhorn time frame. Being a command line/console enthusiast, I find this rather exciting news. Indeed it has been years since MS actually did anything significant to better its command shell – Monad is it.

 

I don’t really know how much I am allowed to talk about Monad itself because of some NDA material, but if you look around on the net you will find a pretty much a lot. One thing about the way the NDA was explained to me recently was that they said – if you can find the material on the web then assume its not under NDA !! (whatever .. )

 

One thing that Monad does differently from other command shells, be it cmd.exe or bash/ksh/csh is that Monad is centered around the idea of an object pipeline. Let me explain:

 

Traditionally one of the ways of defining a console application is to say that it is an application that was access to three streams by default – usually numbered 0,1 and 2 and called the stdin, stdout and stderr. These are text streams. This means that you can read/write text data from these streams.

 

When you pipe the output of one program to another program on the command line, what you are basically doing is that you are ‘connecting’ the stdout of the first process to the stdin of the second process. So text that it is outputted from one process is treated as input text for the next process. This is known territory.

 

For a long time I appreciated the beauty and simplicity of this approach – what could be better, well Monad could be.

 

Monad provides ‘applications’ (I use this term loosely here) on the shell with three streams – but these are not text streams but object streams. Applications that read and write objects in the object pipeline are not traditional processes but are called ‘commandlets’. A cmdlet is actually just a .Net class that is decorated by certain attributes (etc etc).

 

When cmdlets are executed from the msh command line, these classes are instantiated and are given access to the object streams. So one cmdlet writes objects to the output object stream which is read in through the input object stream of the other commandlet. In essence the same idea of piping as with text streams, but this time what passes around are full blown .Net objects.

 

Giving this idea a little thought, you will realize that this makes for much richer shell programming. Like for example a lot of time effort is spent in shell programming (traditionally a unix forte) is scrapping out meaningful values from the output of other commands. Even entire languages (awk) have been created largely for this kind of text scrapping. For example if you do a ps –ax, then you really need to cut out (literally) the columns of text where the process id falls so that you can automatically call a kill command with it.

 

This kind of difficulty completely disappears with Monad simply because the cmdlets down the object stream get full objects and so they can examine the fields of these objects for the parameters they want.

 

Of course this kind of functionality would have been near impossible in the pre .Net era because there was no understandable concept of a ‘type’ that was applicable across languages. The shell being purely a .Net shell the command-lets can talk .Net and can thus consume any .net type. (Remember this is one of the basic tenets of the .Net platform - that its tries to provide a level playing field for languages to interact).

 

When a command let returns a set of types and there are no more command lets in the pipeline to consume to objects then the objects are formatted in some standard way to the console. What that means is that if we have a command called ‘ps’ it would be expected to return a collection of objects each of which represent a running process. Now if at the console I type simply

> ps

then there are no more commandlets that receive the process objects returned by ‘ps’. These objects are formatted in a standard manner to the console so that user can see them. Nice?

 

Monad has really appealed to me in the short time I have spent with it. Traditional shells like bash may have some catching up to do in the light of power like this. Of course Monad is presently at a nascent stage. However for an early pre-beta, Monad is already a very sophisticated and elegant system.

 

I don’t know if I have crashed any NDAs already. I need to check up on that before I continue.

 

 

Next:
Cmdlet parameter binding in Monad 

Other:
Some of my ranting about NDA

Clarifications on NDA related issues about Monad
Pooja on deployment of Monad on 'unsupported' OSes

 

Thursday, June 10, 2004 6:25:24 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Thursday, June 03, 2004

Antonio has a post about generalizing environment classes (that capture state of a closure) with using generic types, such that the class itself captures only the arity of the environment.

 

To quote:

http://rotor.di.unipi.it/cisterni/Lists/My%20Blog/DispForm.aspx?ID=15

In general we may think that the compiler generates several environment classes, for the needed arities; for instance:

 

class Environment3<A, B, C> {

  A a;

  B b;

  C c;

}

 

There is one issue that I can think of, off the top of my head – the CLR has a an excellent approach to generics (among the best I have seen) and is well described in Don Syme’s paper here:

The Design and Implementation of Generics for the .NET Common Language Runtime

http://research.microsoft.com/projects/clrgen/generics.pdf

 

the thing about CLR generics is that they are very efficient for all reference types, because for reference types there is no specialization of templating behavior (as with classical c++ style generics). All reference types use the class definition during runtime.

 

However value types cause the runtime to generate specialized classes to handle type of a value type that is used is a templated entity. Classes definitions are shared by value types only when they share the same foot print with respect to the GC.

 

So it would be better is compiler actually generated specialized classes to hold environment state whenever is knows that the types the environment needs to hold are value types. This simply provides for a performance benefit, because the specialization of the class will not happen at runtime, instead will be done at compile time.

 

 

Antonio also discusses a private member access issue – again I don’t think I fully get him. Assuming the new delegate mechanism is in place we could have classes that look like this

 

class Env

{

        //have only public members

}

 

class Foo

{

        //original method

        void bar()

        {

        }

       

        //anonymous compiler generated method

        void anon_bar()

        {

                //access all members of Foo here

                //access all public members of Env here

        }

}

 

Is there a need to make members to Env private? The entire point of having Env is simply to act as a place holder for some values. Better yet (I don’t know if the old friend method mechanism works), but if friend decls are possible then the anonymous method can be declared as a friend in class Env. This does not add to the class definition in any way, it would simply allow for member access.

 

 

You might want to look at these links to follow the sequence of these posts –

1)       Closures in CLR 2.0

2)       Implementation of Closures (Anonymous Methods) in C# 2.0 (Part 6)

3)       More on CLR 2.0 closures

4)       Closure implementation enhancement in CLR 2.0 using the new delegate mechanism

5)       Again on closures

6)       this post

Thursday, June 03, 2004 12:58:34 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Wednesday, June 02, 2004

This is a tremendously exciting time to be thinking about programming languages and language research. I recently I have come across a lot of material that has made me think a lot.

 

Polyphonic C#

http://research.microsoft.com/%7Enick/polyphony/

            This is a C# like language that is built for concurrency control. Amazing piece of thought exercise there. I recommend looking at Modern Concurrency Abstraction for C#.

 

Xen/X# from Microsoft Research

Xen basically proposes to extend the C# language to better data handling support into the language. 

Unifying Tables Objects and Documents

This should give you a good idea of X#. This is by Erik Meijer of MSR.

Programming with Circles, Triangles and Rectangles

More – interesting reading.

 

C Omega

http://research.microsoft.com/Comega/

A combination of Xen and Polyphonic C#.

You might want to download this ppt that discusses C Omega by none other than Damian Watkins of MSR.

 

Groovy

http://groovy.codehaus.org/

            Groovy is the Ruby like language for the JVM. Ruby itself takes from the power of dynamic object oriented-ness that was so characteristic of smalltalk and whips a powerful expressive language on it. The thing is that Groovy also builds in Xen like concepts.

You might want to download this ppt that discusses Groovy by James Strachan co-author of groovy.

 

Self

http://research.sun.com/self/language.html

An old language from Sun Microsystems. Reading up about self makes you appreciate the spirit of many message passing and prototypes and cloning based pure object oriented systems.

 

 

 

I am not mentioning functional languages here because it is not fair to put up stuff I have no clue about. I must say this is an amazing time to be interested in programming languages.

 

Wednesday, June 02, 2004 7:35:22 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Friday, May 28, 2004

I had dropped a link to Antonio Cisternino’s blog entry about Closure support in CLR 2.0 when I was writing a description of how the C# compiler (Whidbey release) implements closures.

 

I was completely wrong about what Antonio’s blog entry was about. For some reason, my head being so full of C# that it is, I assumed he was talking about the how closures were implemented in C# for the Whidbey release. Closures in the Whidbey release (Visual Studio 2005) are officially called anonymous methods. So apologies Antonio, I had missed the point.

 

That said, what Antonio was referring to was a subtle change in the implementation of the delegates in CLR 2.0 so that the future CLR can be better used to implement closures and support functional languages and constructs. I exchanged some mails with him and I think I get what he was talking about.

 

Before I go any further I would recommend you reading Antonio’s original entry

Closures in CLR 2.0, my entry about the implementation of closures in C# 2.0 using delegates as they are available in CLR 1.x and Antonio’s follow-up entry that speaks of the distinguishing aspect of the new delegate implementation: More about Closures in CLR 2.0

 

The following are derived from mail exchanges with Antonio.

 

A delegate can be thought of as an entity that holds a pointer to a function and optionally a reference to the object for which the function is supposed to be an instance function. In CLR 2.0 a simple and subtle change has taken place where in the constraint that the instance pointer has to refer to the object for which the function pointer is member function, has been removed. The function pointer and the object reference don’t have to be related to each other.

 

In functional languages delegates are often implemented by having a pointer to a function which is the block of code that belongs to the closure and a pointer to an instance of the environment. The environment is the entity that holds the state for the code in the closure block.

 

In C# 2.0 the environment object is implemented by creating a class for every function that wraps a closure and shares state with it. Such a class is generated name-mangled as __LocalsDisplayClassXXX in C# 2.0.

 

The code that is part of the closure is now part of the environment class. When a closure is created an instance of the environment class is created and a delegate is returned to the instance and its member function that wraps the closure code. This is what could be done with CLR 1.x delegates as the function had to be a member of the environment class.

 

With CLR 2.0 delegates, what the compiler writers now have the option of doing is that they can generate a common environment class for all functions that wrap closures that need to capture similar information about its environment.

 

Here is an example and some notes courtesy of Antonio:

 

Closures in functional programming languages are often implemented with pointers pairs (env, func) where env is the pointer to the environment of the closure, and func is a pointer to a function whose first argument will be env.

 

With CLR 1.0 this cannot be achieved because delegates are pairs but with an additional constraint: func should be declared in the class of env.

The problem with this additional constraint on delegates is that you tend to define a class for each closure you make. In a functional programming language you'll pay a significant overhead because for each closure you have to introduce a private class with the environment and the code.

 

Besides removing that constraint (as it has been done in CLR 2.0) you can define a class with plenty of static methods, one per closure and define a type for each possible environment. This reduces the number of types you need to have.

 

For instance:

 

void foo() {

 string s;

 Cmd d = { Console.WriteLine(s); }

 //...

}

 

void baz() {

 string s;

 Cmd d = { Console.WriteLine("Hello {0}", s); }

 //...

}

 

The current compiler generates two classes both having a single int field.

With CLR 2.0 the compiler could use a single class as follows:

 

class Env_String {

 string f;

}

 

void f(Env_String env) { Console.WriteLine(env.s); }

void g(Env_String env) { Console.WriteLine("Hello {0}", env.s); }

 

void foo {

 Env_String env = new Env_String();

 Cmd d = (Cmd)Delegate.CreateDelegate(typeof(Cmd), env,

GetType().GetMethod("f"));

 //...

}

 

void baz {

 Env_String env = new Env_String();

 Cmd d = (Cmd)Delegate.CreateDelegate(typeof(Cmd), env,

GetType().GetMethod("g"));

 //...

}

 

In the above case the environment class need be only one, as in both the closures, the environment needs to capture the state of only a string variable. The environment class itself can be kept free of the closure specific code and the methods that are generated for the closure can be placed in the class that the original enclosing method was a part of.

 

This subtle thing had escaped my thinking for sometime. I guess when you are doing your PhD with a university that hosts one of the worlds largest .Net user-groups and are working with matters related to MSR Cambridge, you tend to pick up subtle things a lot easier. :-)

 

There is one thing that has me thinking is about the implementation of closures in the case of closures being defined inside instance methods. If you refer here, I show a screen shot of an ildasm of that case.

 

When an instance function is being used the environment will have to have a ‘this’ pointer member that the closure block can access to access any class data members. When the C# compiler is generating one class per function wrapping a closure the ‘this’ can be statically typed to the type of the class that contained the parent method.

 

 

If the environment class is to be shared across multiple classes that implement closures, then what will be the type of the ‘this’ pointer?

 

I am guessing here, but I would expect that they might choose to create the environment class as generic class that is type independent on the ‘this’ pointer. Do you think that sounds right? What are the possible fallouts with that approach? Generic environment classes.

 

As a matter of fact when you dive into the possibility that generics opens up, it’s rather interesting. We could have the entire environment as a class that contains templated / generic types for every reference type member. This might be efficient to implement because the implementation of generics in the .Net framework does not involve specialization of the runtime class for reference types. Even for value types, I believe it does optimizations to avoid class duplication if the value types have similar footprints as far as the GC is concerned.

 

One thing is for sure, the future looks interesting for functional and dynamic languages leveraging the CLR.

 

Among other things, I am looking forward to the MVP India summit that should be happening this weekend 28th May to 31st May.

 

 

Friday, May 28, 2004 1:16:56 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Sunday, May 23, 2004

How many of us recognize the name of this man?

 

Mitch Kapor was the founder of the Lotus corporation. He was the man who designed the Lotus 1-2-3. If you know you history, Lotus was one of the only large applications companies that was a serious challenger for Microsoft in its early years. There were years spent over the battle for the spreadsheet that was fought on both the old Mac as well as the old DOS machines.

 

Microsoft’s offering those days were called Multiplan. Multiplan was fairly beat by Lotus 123 in almost all fronts. Microsoft eventually thought through their faults and strengths and eventually released Excel – the spreadsheet battle was over.

 

Mitch Kapor himself, is one person I think of as being fairly amazing.

 

He was co founder of the EFF, the Electronic Frontier Foundation along with John Perry Barlow. The EFF was the organization that for the first time stood up for hackers rights and digital rights. This was of significant and epic proportions in the early 90s when hacker arrests and crackdowns were gaining a witch-hunt like momentum.

 

“The EFF is a non-profit civil liberties organization working in the public interest to protect privacy, free expression, and access to public resources and information online, as well as to promote responsibility in new media.”

 

The EFF was the organization that for the first time took the American Secret Service to court over the ruling and prosecution of the ‘hacker’ Knight Lightning. The EFF won and it literally brought the end of an era about how people of ‘hackers’ and the rules for information security.

 

I highly recommend reading this book called the Hacker Crackdown by Bruce Sterling. The book reflects the ethos of a time when the parameters of information security were very different from how we think of them now. Considering the license of the book, what it intends to convey and what I hope it may change about your thinking, I would recommend downloading a softcopy of the book.

 

Today I happened to come across Mitchell Kapor’s website and blog.

Website: http://www.kei.com/homepages/mkapor/

Blog: http://blogs.osafoundation.org/mitch/

 

I found this entry, right on top and I couldn’t help smiling:

 

May 09, 2004

Now I'm Mad

 

Some idiot Atkins Diet spammer just posted 53 bogus comments in this blog. I'm disabling comments (globally) shortly and figuring out if there's any recourse.

 

They don't know it yet, but they picked the wrong person to do this to.

 

 

Sunday, May 23, 2004 8:24:41 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Saturday, May 22, 2004

C# 2.0 has support for closures.

 

This article discusses the implementation of the closures in the C# language and how this has been done using pure compiler magic without any CLR changes. I had previously mentioned C# closures in an earlier blog entry and had linked to Antonio Cisternino’s blog entry:

Closures in CLR 2.0

This is an interesting entry and worth a read. Unfortunately, IMO, Mr. Cisternino’s entry is a not correctly titled. The support for closures is a C# only thing not a CLR level addition.

 

I intend to start off where his blog entry ends. Here I shall look into how it is done.

 

Features such as closures have been taken to legendary fame in languages like scheme and ruby. Recent language developments like Groovy also ship with closure constructs.

 

Microsoft, for some reason, has been calling the new feature of the language as anonymous methods. I don’t know why this feature hasn’t been publicly been spoken of as closure or lambda support in the C# language. Maybe there are subtle differences in the theoretical definition of closures and what the C# language achieves.

 

That said – let’s jump into the matter.

This is C# code that shows off a closure:

 

Code Showing One Anonymous Method / Closure that shares variables with its scope

//closure.cs

//Compile: csc closure.cs

using System;

 

class CMain

{

      delegate void Closure(int n);

     

      static Closure CreateClosure()

      {

            int c = 0;

            return delegate(int n) {

                  Console.WriteLine("Closure: n = {0}, c = {1}",n,c++);

            };

      }

     

      static void Main()

      {

            Closure c1 = CreateClosure();

            Closure c2 = CreateClosure();

            c1(1);

            c1(1);

            c1(1);

            c2(2);

            c2(2);

            c2(2);

      }

}

 

This code is very similar to the groovy snippet I had posted sometime back. When executed, this is the output:

 

> closure.exe

Closure: n = 1, c = 0

Closure: n = 1, c = 1

Closure: n = 1, c = 2

Closure: n = 2, c = 0

Closure: n = 2, c = 1

Closure: n = 2, c = 2

 

If you don’t know what closures are about, the easiest way to appreciate them is to take a careful look at the C# code above. Notice the function CreateClosure() is returning a delegate to a block of code that is part of the function itself. (Normally you would create a delegate to a function). If you don’t understand what a delegate is, let it be. What you need to understand is that the function returns a block of code that is a part of the function.

 

The block of code accepts an integer parameter. Also, you will notice that the local variable of the function (variable ‘c’) is being used in the code block.

 

When the block of code is returned to the caller (in this case main), the Main() can invoke the variable that represents the block of code, causing the code to run.

 

Once upon a time you could create a delegate to an independent function only and not to a code block within a function. A delegate to a function had to have the same signature as the function. The delegate could be thought of as an old C style function pointer. When the delegate is invoked, the function pointed to is called. Delegates came with the additional merit that they were type safe function pointers – most people did not think much more than that about delegates.

 

Now it is a little different. While the anonymous method within the CreateClosure() method actually looks like it simply has a nested function that does not have a name explicitly provided its not that simple. You might venture to guess that the compiler actually goes on to create a new method (by extracting this code block) and simply creates a delegate to the new function, the same way delegates once used to behave.

 

However, notice that the code block uses variable ‘c’ that is defined locally to the enclosing function. If this code block is going to be carved out of the enclosing function, how can it access variable ‘c’? Better yet, take a closer look at the output.

 

It looks like a closure returned from a call to CreateClosure() is seems to remember its value of the variable ‘c’. Some how, the state of the function CreateClosure() is captured in the delegate/closure that it returns. So much so, that the state of two invocations of CreateClosure() seemed to be maintained independent of each other.

 

This is in violation of the way simple C like functions work, where the function state is stored on the stack and the functions stack frame is torn down from the stack and state is lost when the functions return. (Refer ‘The Big Deal about Iterators’)

 

Functions that return closures seemed maintain state even after they have returned. The closure object is maintains a reference to that state. This requirement of maintaining is similar to the implementation of iterators (if you give it some thought).

 

Implementation

This is what our closure.cs looks like under ILDASM.

 

 

Notice the new class called __LocalsDisplayClass$0…1 that has been created. This is interesting culprit.

 

In essence how closures work in C# 2.0  is that the compiler creates a new class that contains member variables correspond to the local variables of CreateClosure() that are being used in the closure/anonymous method that it defines. Thus you can see the local variable ‘c’ of method CreateClosure() can be seen in class __LocalsDisplayClass$0…1.

 

So calling the CreateClosure method creates an instance of the __Locals… class. It then creates an old (classical) delegate to the __AnonymousMethod$0… method of the class. So the actual support for delegates in the CLR hasn’t changed at all. The delegate that is returned from the CreateClosure() method is a normal (old C# 1.x type) delegate.

 

All access to variables that are shared between the CreateClosure() method and the anaymous method are accesses to members of the __Locals… class.

 

Here is IL code of CreateClosure()

 

.method private hidebysig static class CMain/Closure

        CreateClosure() cil managed

{

  // Code size       30 (0x1e)

  .maxstack  3

  .locals init (class CMain/__LocalsDisplayClass$00000001 V_0,

           class CMain/Closure V_1)

  IL_0000:  newobj     instance void CMain/__LocalsDisplayClass$00000001::.ctor()

  IL_0005:  stloc.0

  IL_0006:  ldloc.0

  IL_0007:  ldc.i4.0

  IL_0008:  stfld      int32 CMain/__LocalsDisplayClass$00000001::c

  IL_000d:  ldloc.0

  IL_000e:  ldftn      instance void CMain/__LocalsDisplayClass$00000001::__AnonymousMethod$00000000(int32)

  IL_0014:  newobj     instance void CMain/Closure::.ctor(object,

                                                          native int)

  IL_0019:  stloc.1

  IL_001a:  br.s       IL_001c

  IL_001c:  ldloc.1

  IL_001d:  ret

} // end of method CMain::CreateClosure

 

Notice some things in the above code

- An object of __LocalsDisplayClass$00000001 is created.
- Access to the variable is actually access to the member ‘c’ of this class.
- The delegate is created to the instance of the __LocalsDisplayClass$00000001 class that was created and its __AnonymousMethod$00000000 method.

 

This is the code of the anonymous method, which has now become CMain/__LocalsDisplayClass$00000001::__AnonymousMethod$00000000(int32)

 

.method public hidebysig instance void  __AnonymousMethod$00000000(int32 n) cil managed

{

  // Code size       39 (0x27)

  .maxstack  5

  .locals init (int32 V_0)

  IL_0000:  ldstr      "Closure: n = {0}, c = {1}"

  IL_0005:  ldarg.1

  IL_0006:  box        [mscorlib]System.Int32

  IL_000b:  ldarg.0

  IL_000c:  dup

  IL_000d:  ldfld      int32 CMain/__LocalsDisplayClass$00000001::c

  IL_0012:  dup

  IL_0013:  stloc.0

  IL_0014:  ldc.i4.1

  IL_0015:  add

  IL_0016:  stfld      int32 CMain/__LocalsDisplayClass$00000001::c

  IL_001b:  ldloc.0

  IL_001c:  box        [mscorlib]System.Int32

  IL_0021:  call       void [mscorlib]System.Console::WriteLine(string,

                                                                object,

                                                                object)

  IL_0026:  ret

} // end of method __LocalsDisplayClass$00000001::__AnonymousMethod$00000000

 

This is quite exactly the code that we had written into the CreateClosure() function. Except that the local variable ‘c’ is not a local variable any more.

 

What do you think will happen when there is a function that defines two anonymous methods within it?

 

Code Showing Multiple Anonymous Methods / Closures that share variables with its scope

//closure2.cs

//Compile: csc closure2.cs

using System;

 

class CMain

{

       delegate void Closure(int n);

       static Closure t1,t2;

      

       static void CreateClosure()

       {

              int c1 = 0;

              int c2 = 0;

              int c3 = 0;

              int c4 = 0;

              Console.WriteLine("c4 = {0}",c4);

             

              t1 =  delegate(int n) {

                     Console.WriteLine("Closure: n={0}, c1={1}, c2={2}",

                                n,c1++,c2++);

              };

              t2 = delegate(int n) {

                     Console.WriteLine("Closure: n={0}, c1={1}, c3={2}",

                                n,c1++,c3++);

              };

       }

      

       static void Main()

       {

              CreateClosure();

       }

}

 

 

This is what happens:

 

 

Notice:

- There is still only one class that maintains state.
- The class has two methods (one for each of the anonymous methods)
- The variables that are being used by either of methods are part of the class (c1,c2, c3).
- Variables that are not being used from either closure are not part of the class (c4 is omitted).

 

One final look, what if the closure does not use any variables of its enclosing scope, how would this work?

 

Code Showing an Anonymous Method / Closure that is stateless

//closure3.cs

//Compile: csc closure3.cs

using System;

 

class CMain

{

       delegate void Closure(int n);

      

       static Closure Cre