Lambda Expressions and Closures

25.1 Lambda Syntax

Dim square = Function(x As Integer) x * x                 ' single-line function lambda
Dim greet = Sub(name As String) Console.WriteLine($"Hi {name}")   ' single-line sub lambda
Dim add As Func(Of Integer, Integer, Integer) = Function(a, b) a + b   ' types inferred from the delegate

Dim classify = Function(n As Integer) As String               ' multi-line lambda
                   If n < 0 Then Return "negative"
                   If n = 0 Then Return "zero"
                   Return "positive"
               End Function

Dim logAll = Sub(items As IEnumerable(Of String))
                 For Each i In items
                     Console.WriteLine(i)
                 Next
             End Sub

Dim asyncLambda = Async Function() As Task(Of String)
                      Await Task.Delay(100)
                      Return "done"
                  End Function

25.2 Closures

Closures capture variables by reference. Watch for loop variables in deferred execution.

Function MakeCounter() As Func(Of Integer)
    Dim count = 0
    Return Function()
               count += 1
               Return count
           End Function
End Function

Dim counter = MakeCounter()
Console.WriteLine(counter())   ' 1
Console.WriteLine(counter())   ' 2

Function Multiplier(factor As Integer) As Func(Of Integer, Integer)
    Return Function(x) x * factor
End Function
Dim triple = Multiplier(3)
Console.WriteLine(triple(10))  ' 30

25.3 Higher-Order Functions

Function ApplyTwice(f As Func(Of Integer, Integer), x As Integer) As Integer
    Return f(f(x))
End Function
Console.WriteLine(ApplyTwice(Function(n) n + 5, 1))   ' 11

Function Compose(Of A, B, C)(f As Func(Of B, C), g As Func(Of A, B)) As Func(Of A, C)
    Return Function(x) f(g(x))
End Function