Tra le novità di C#3.0 e VB9 sicuramente le lambda expressions sono le più "ostiche" da comprendere, vuoi per il nome che incute timore smile_teeth, vuoi per lo strano simbolo "=>" che si legge "Goes To" oppure semplicemente perchè incontrate per la prima volta con LINQ e quindi in un contesto di per se non chiaro, almeno inizialmente.
In realtà le lambda altro non sono che una versione riveduta ed "epurata" degli anonymous methods che chi usa C#2.0 sicuramente conosce e utilizza.

Consideriamo tre delegates:

   1:  delegate int Sum(int a, int b);
   2:  delegate T MyFunc <T> (T a, T b);
   3:  delegate void InvokeMethod();
 

Supponiamo ora di volere associare un metodo al delegate 1 usando la modalità "classica".

   1:  Sum sd0=new Sum(CalcSum); // alternativa: Sum sd0=CalcSum;
   2:  int val=sd0(4,5);
 
.
   1:  private int CalcSum(int a, int b){
   2:    return a+b;
   3:  }

Usando gli anonymous methods lo stesso delegate in C#2.0 può essere invocato in questo modo:

   1:   Sum sd0=delegate(int a, int b)
   2:    {
   3:      return a+b;         
   4:    };
   5:    int val = sd0(4, 5);

Immaginiamo ora di rimuovere alcune informazioni "superflue" come la keyword delegate, aggiungendo il simbolo "=>" tra i parametri e il corpo del anonymous method e spostando tutto su una singola riga:

   1:   Sum sd0=(int a, int b)=>{return a+b;};
 

Et voilà ecco una lambda expression... (o statement lambda se preferite...)

Visto che il compilatore C#3.0 è molto smart è possibile semplificare ulteriormente l'espressione facendo dedurre il tipo di a, b e quello di ritorno dal delegate Sum al quale la lambda è associata e rimuovere la keyword return ottenendo:

   1:  Sum sd0= (a,b)=>(a+b); 
   2:  int ret=sd0(4,5);

Nel caso ci sia un solo parametro le parentesi si possono eliminare come nel caso di un ipotetica funzione IncreaseByOne

   1:  IncreaseByOne PlusOne= a=>a++; 
   2:  int ret=PlusOne(3);

In assenza di parametri, come nel caso del delegate 3, le parentesi devono necessariamente essere specificate:

   1:  InvokeMethod im= ()=>Console.WriteLine("Invoked");
   2:  im(); 

Il delegate 2 rappresenta un generica funzione MyFunc che opera e restituisce un tipo T, in questo caso in base a quanto detto finora è quindi possibile dichairare una lambda expression Multiply in questo modo:

   1:  MyFunc<int> Multiply=(a,b)=>a*b;
   2:  int ret=Multiply(3,2);

In realtà il delegate 2 è inutile, in quanto nel framework 3.5 esiste già un delegate generico Func<T,TResult> con vari overload che rappresenta una generica funzione con un numero variabile di parametri T in ingresso (da zero a quattro) e un generico valore TResult (definito in ultima posizione) di ritorno. Di conseguenza l'esempio precedente può essere riscritto come segue:

   1:  Func<int,int,int> Multiply=(a,b) => a*b;
   2:  ret=Multiply(4,5);

Il codice eseguito dalla lambda è stato fin'ora composto da espressioni molto semplici (tipo a+b), C#3.0, a differenza di VB9, consente di definire dei lambda statements ovvero delle lambda che contengono più di una semplice espressione e che sono, a tutti gli effetti, degli anonymous methods come nell'esempio seguente:

   1:  Func<int,int,int> DoSomeProcessing=(a,b) =>
   2:   {
   3:      int newValue=CalcSum(a,b);         
   4:      return a*newValue;
   5:   };
   6:   string  ret=DoSomeProcessing(2,3);

Expression Trees

Una lambda expression può essere definita attraverso un Expression Tree ovvero una classe Expression<T> definita in System.Linq.Expression con la differenza che in questo caso l'espressione viene effettivamente trasformata in codice IL al momento della sua esecuzione e non a compile time e questo IL costruisce un albero di expressioni che descrivono la lambda expression associata.
L'utilizzo delle Expression Tree è legato ai Query providers di LINQ percui, come MSDN stesso cita, a meno che non dobbiate creare un vostro specifico LINQ provider o un vostro query language potete ignorare i dettagli relativi agli expression trees.
Riprendendo la lambda expression precedente

   1:  Sum sd0= (a,b)=>(a+b); 

ecco come esprimerla usando un expression tree:

   1:  Expression<Func<int,int,int>> expression=(a,b) =>a+b;
   2:  ret=expression.Compile()(4,5);

notate, come in questo caso sia necessario compilare l'espressione attraverso il metodo Compile prima di poterla utilizzare.

VB9

La sintassi per definire delle lambda expression in VB9 sfrutta la keyword Function, rifacendoci all'esempio precedente ecco come associare un delegate Sum ad una lambda expression (il codice richiede la June CTP o successiva)

   1:  Public Delegate Function Sum(ByVal a As Integer, ByVal b As Integer) As Integer
   2:  ...
   3:  Dim DoSum As Sum = Function(ByVal a, ByVal b) a + b
   4:  Dim ret As Integer = DoSum(4, 5)
   5:   
   6:  'Opzione che usa i named arguments
   7:  ret = DoSum(b:=3, a:=4)

Dalla Beta2 la definizione della lambda verrà ulteriormente semplificata rimuovendo il modificatore ByVal che precede i parametri, nella June CTP non è possibile rimuoverlo.
Come accennato in precedenza VB9 permette di definire delle lambda expressions ma non dei lambda statements, ciò si traduce nel fatto che in VB9 manca una vera implementazione degli anonymous methods smile_sad, a differenza di C# è però possibile associare una lambda expression ad una variabile il cui tipo è dedotto implicitamente (Option Infer On) ovvero:

   1:  Dim Increase = Function(ByVal a As Integer) a + 1
   2:  Dim x As Integer = Increase(2)

Ovviamente le lambda entrano prepotentemente in gioco nell'architettura di LINQ, ma come avete potuto vedere possono essere sicuramente utili in parecchie altre occasioni.