Lambda Calculus et al in C# 3.0 / VS 2008 / .NET 3.5#

Visual Studio 2008 VHD makes life a lot easier if you want to explore the upcfeature-set of  C# 3.0 compiler. Make sure to get the differencing image Visual Studio Code Name Orcas Base Image else you’d be getting the following error.

"OrcasBeta2_VSTS" could not be started because a disk-related error occurred.

Feeling bad for fellow .netters (Yes Ben, its you) who had to clean install the beta2 upgrade from beta1. For me, it was plugging in the new machine :) VM Rocks..errr...I meant virtual PC VM, not the other VM.

Anyhow, support for lambda expressions is one of the gems in C# 3.0, as defined in the C# 3.0 Language Specification

lambda-expression:
(   lambda-parameter-listopt   )   =>   lambda-expression-body
implicitly-typed-lambda-parameter   =>   lambda-expression-body

This is essentially the same thing you’d do in CLisp, the function definition, application and recursion, all in quite elegant way. Therefore, the implication inherently defines the method without any explicit declaration. So you can say

x => x + 1 which translates to a function that takes one argument, c, and returns the value x + 1.

A less trivial example is as follows.

List<string> XFilesEpisodes = new List<string>();
XFilesEpisodes.Add("Little Green Men");
XFilesEpisodes.Add("The Host");
XFilesEpisodes.Add("Blood");
XFilesEpisodes.Add("Sleepless");
XFilesEpisodes.Add("Duane Barry");
string episodeMatch = XFilesEpisodes.Find(p => p.Equals("Sleepless"));
Console.WriteLine(episodeMatch);
Console.Read();

p => p.Equals("Sleepless")); expands to the

 string episodeMatch = XFilesEpisodes.Find(delegate(string name) {
                           
return XFilesEpisodes.Equals("Sleepless");
                        });

The lambda methods evaulated within closures; these anonymous delegated blocks are not called closures because their understanding would give closure to your intellectual feat but because they can access the local members. As defined on precious wikipedia (since I can never find my PL book handy), a closure is a function that is evaluated in an environment containing one or more bound variables. When called, the function can access these variables.

Now on the IL level, this can be seen as a static predicate class of anonymous delegate (hence the expansion)


.field private static class [mscorlib]System.Predicate`1<string> '<>9__CachedAnonymousMethodDelegate1'

.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )

It is defined as anonymous delegate in the general metadata and further performs a string comparison with virtual call (in bold below). 

.method private hidebysig static bool  '< Main>b__0'(string p) cil managed
{
  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
 
// Code size       12 (0xc)
  .maxstack  8
  IL_0000:  ldarg.0
 
IL_0001:  ldstr      "Sleepless"
  IL_0006:  callvirt   instance bool [mscorlib]System.String::Equals(string)
  IL_000b:  ret
} // end of method Program::'< Main>b__0'

The Main method is as follows which shows the generic list of items and then the actual call to CachedAnonymousMethodDelegate.
 
.method private hidebysig static void  Main (string[] args) cil managed
{
  .entrypoint
  // Code size       110 (0x6e)
  .maxstack  4
  .locals init ([0] class [mscorlib]System.Collections.Generic.List`1<string> XFilesEpisodes,
           [1] string episodeMatch)
  IL_0000:  newobj     instance void class [mscorlib]System.Collections.Generic.List`1<string>::.ctor()


.......

  IL_003e:  ldsfld     class [mscorlib]System.Predicate`1<string> VS.NET2008Features.Program::'<>9__CachedAnonymousMethodDelegate1'
 
IL_0043:  brtrue.s   IL_0056
  IL_0045:  ldnull
 
IL_0046:  ldftn      bool VS.NET2008Features.Program::'<Main>b__0'(string)
  IL_004c:  newobj     instance void class [mscorlib]System.Predicate`1<string>::.ctor(object,

                                                                                       native int)
 IL_0051:  stsfld     class [mscorlib]System.Predicate`1<string> VS.NET2008Features.Program::'<>9__CachedAnonymousMethodDelegate1'

  IL_0056:  ldsfld     class [mscorlib]System.Predicate`1<string> VS.NET2008Features.Program::'<>9__CachedAnonymousMethodDelegate1'

  IL_005b:  callvirt   instance !0 class [mscorlib]System.Collections.Generic.List`1<string>::Find(class [mscorlib]System.Predicate`1<!0>)

  IL_0060:  stloc.1

  IL_0061:  ldloc.1

  IL_0062:  call       void [mscorlib]System.Console::WriteLine(string)

  IL_0067:  call       int32 [mscorlib]System.Console::Read()

  IL_006c:  pop

  IL_006d:  ret

} // end of method Program::Main

The extension methods are a very powerful feature. Think of them as highly sophisticated version of poor man’s global overrides. For instance, in the example below I’d convert all the temperature by “extending” the method on the double type which does not define a Convert method.


namespace VS.NET2008Features
{
   static class Program
   {
       static void Main(string[] args)
       {
           double temperature = 0;
           temperature.Convert();
           Console.Read();
       }

       static void Convert(this double temp)
       {
           double tempF = (9/5)* temp +32; // 9/5.0 not done on purpose.
           Console.WriteLine(tempF);
       }
   }

}

For a simple program like this, the underlying IL and reflector code looks quite interesting. First of all, note the clever IL as it will evaluate the 9/5 as 1 (integer value) since it is not a double calculation (9/5.0 would have been). Also, the extension attribute is added and redirection to this new extended method is done at the IL level. Clever eh?
 

private static void Main(string[] args)
{
    0.Convert();
    Console.Read();
}

private static void Convert(this double temp)
{
    double num = (1 * temp) + 32;
    Console.WriteLine(num);
}

.method private hidebysig static void  Convert(float64 temp) cil managed

{

  .custom instance void [System.Core]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 )

  // Code size       29 (0x1d)

  .maxstack  2

  .locals init ([0] float64 tempF)

  IL_0000:  ldc.r8     1.

  IL_0009:  ldarg.0

  IL_000a:  mul

  IL_000b:  ldc.r8     32.

  IL_0014:  add

  IL_0015:  stloc.0

  IL_0016:  ldloc.0

  IL_0017:  call       void [mscorlib]System.Console::WriteLine(float64)

  IL_001c:  ret

} // end of method Program::Convert

.method private hidebysig static void  Main (string[] args) cil managed

{

  .entrypoint

  // Code size       23 (0x17)

  .maxstack  1

  .locals init ([0] float64 temperature)

  IL_0000:  ldc.r8     0.0

  IL_0009:  stloc.0

  IL_000a:  ldloc.0

  IL_000b:  call       void VS.NET2008Features.Program::Convert(float64)

  IL_0010:  call       int32 [mscorlib]System.Console::Read()

  IL_0015:  pop

  IL_0016:  ret

} // end of method Program::Main

The extension method is depicted here by setting the extension attribute in the CLR. The call to the Convert gets translated and redirected to VS.NET2008Features.Program::Convert(float64)

Scott Guthrie defines it best, from both developer and framework architect prospective. And till then, I'm waiting for Jeffrey Richter's addendum to CLR via C# which would discuss the C# 3.0 enhancements.





8/21/2007 12:01:30 AM (Pacific Standard Time, UTC-08:00) #    Comments [4]  |  Trackback

 

Teaching WCF at UCSD Extenstion#
Starting from this Thursday, I’ll be teaching “Programming Windows Communication Foundation” classes at University of California, San Diego Extension Program.

The classes are scheduled every Thursday, 6:35 p.m. - 10:00 p.m. from 8/16/2007 - 9/20/2007 (6 mtgs.). Further details and the enrollment details can be found at the following link.

WCF Course -UCSD Extension
CSE-40114  Credit: 3 units
“.NET 3.0 introduces Windows Communication Foundation (WCF) providing a service-oriented programming model for distributed application development. This course will use the C# programming language and cover designing, implementing, configuring and hosting WCF servers and clients to leveraging this new communication stack and its protocol facilities for security, reliability, transactions and other services.”

The course’s text book is Michele Bustamante’s “Learning WCF – A Hands on Guide”. The source code for the book labs can be downloaded from here. We will be discussing a lot of interesting topics in WCF and connected systems so spread the word.





8/13/2007 10:11:51 PM (Pacific Standard Time, UTC-08:00) #    Comments [0]  |  Trackback

 

Links Extravaganza - KDD, Data Mining, Video Lectures etc #
Machine Learning Course
Machine Learning Video Lectures Compiled in Course Form.

Statistical Aspects of Data Mining
Video Lectures on Statistical Aspects of KDD and DM.

Undocumented Fusion
One of the most interesting undocumented jewel.

The TETRAD Project:
Causal Models and Statistical Data

19 Eponymous Laws Of Software Development
Interesting compilation by Phil Haack

Ethical Hacking and Countermeasures
I'm planning to take CEH Certification this fall as soon as I'm done with my MCPD

Sql Server Locking and the ADO.Net SqlDataReader
This is a issue we recently encountered; Jeff did a great job explaining it.

Video Lectures
Excellent Video Lectures on Computer Science and Related Topics

MIT OCW - Introduction to Algorithms
MIT open courseware course

MIT Math Lectures (Differential Equations, Linear Algebra et al)

Lectures Online
Math Lectures

The National Security Archive (George Washington University)
Interesting docs archive.

CCSU data Mining Program and Resources
Central Connecticut University Offering MS in Data Mining





8/13/2007 9:56:55 PM (Pacific Standard Time, UTC-08:00) #    Comments [0]  |  Trackback

 

All content © 2008, Adnan Masood
About the Author
On this page
Calendar
<October 2008>
SunMonTueWedThuFriSat
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678
Archives
Sitemap
Blogroll OPML
microsoft