Using Multi-Line Lambda Expressions in VB 2010

Introduction

The Microsoft VB and C# programming teams have merged. (Refer to the MSDN article What’s New in Visual Basic 2010.) Hopefully this will no longer mean competition, but a healthy dose of reality injected into the VB language. Yes, VB is originated as a different tool perhaps with a different agenda geared towards developer simplicity, but in actuality VB 2010 sits on top of the same .NET framework and has all the power that ensues. VB is not and should not be a ‘tinker’ toy, business application-only tool, or a limited, lightweight tool for developers.

Already good things are coming out of Redmond with the latest release, VB 2010. Things like automatic properties and balanced support for Lambda expressions–with Lambda Subs and multi-line Lambda expressions. Let’s take a look at multi-line Lambda expressions, so you can figure out how to incorporate this cool language feature into your day to day programming.

What is a Lambda Expression?

Functions have evolved. Early on all we had was functional programming based on global variables and functions. With the incorporation of object-oriented constructs like the class functions became members and state was no longer global, or at least that is how it should be.

Next, and fairly recently, the anonymous method and anonymous delegate were introduced to make it simpler to do things like assign very short handlers for events. Anonymous methods leave things like visibility qualifiers, method names, and method argument types on the cutting room floor. A Lambda Expression is the next evolution of short methods.

A Lambda Expression is an even more condensed version of the anonymous method. They exist because extension methods like IEnumerable, Where accept arguments of Action(Of T), Func(Of T), and Predicate(Of T) and it is challenging to syntactically put a full blown method in the function argument parameters, but a Lambda Expression is much more compact and visually fits much better. In short, Lambda Expressions support extension methods which in turn support LINQ (Language Integrated Query). The code in Listing 1 demonstrates a simple Lambda Function and Lambda Sub respectively.


Module Module1

   Sub Main()

     Dim IsEven As Func(Of Integer, Boolean) = Function(I) I Mod 2 = 0
     Dim print As Action(Of String) = Sub(s) Console.WriteLine(s)

     Console.WriteLine(“{0} is even: {1}”, 3, IsEven(3))
     print(“Welcome to Valhalla Tower Material Defender!”)

     Console.ReadLine()

   End Sub

End Module




Listing 1: Simple Lambda function and Lambda Sub.

The Lambda function assigned to the variable IsEven accepts an Integer and returns a Boolean, testing to determine if the input argument is even or not. You could use a simple function like this to determine if a sales purchase qualified for a discount or not, for example. The Lambda Sub is just shorthand for Console.WriteLine. I might occasionally use something so simple to add a timestamp to a Trace method to aid in debugging. In case it is not clear the Lambda Expressions are on the right-hand side of the assignment operator.

A sort of incidental feature of Lambda expressions is that they can also imitate nested functions and of course they can be passed around as arguments to other methods to create very dynamic behaviors. Pass a Lambda Expression to a method, call it from that method, and the method’s behavior changes at runtime.

Implementing Multi-Line Lambda Expressions

A multi-line Lambda Expression is just a Lambda Expression with more than one statement. When you use multiple statements you need to add the End Sub or End Function bits to the Lambda Expression; the result is that the Lambda Expressions are a little longer and look a bit more like a traditional function or sub-routine.

Multi-line Lambda Expressions go anywhere a singly-lined Lambda might go, just extra statements. Suppose for example you wanted a Lambda Expression that split a string into a string array, removing white space and changing all words to lowercase words. You could use a multi-line Lambda Function to accomplish this. Listing 1 demonstrates one solution to the defined problem.


Module Module1

   Sub Main()

     ‘ split string into arrray, remove whitespace and lowercase
     Dim splitter As Func(Of String, String()) =
       Function(input)
         Dim separators As Char() = {Chr(32), “,”, “-“}
         Dim strArray As String() = input.Split(separators,
           StringSplitOptions.RemoveEmptyEntries)
         For i As Integer = 0 To strArray.Count – 1
           strArray(i) = strArray(i).ToLower()
         Next
         Return strArray
       End Function

     Const s As String =
       “The time has come the Walrus said, to talk of many things ” +
       “Of Shoes–Of Ships–Of Sealing Wax–Of cabbages and Kings”

     Array.ForEach(splitter(s), Sub(str) Console.WriteLine(str))
     Console.ReadLine()

   End Sub

End Module




Listing 1: Using a multi-line Lambda Expression to parse a string, remove punctuation, and change all words to lower case words.

The splitter variable is assigned to a multi-line Lambda Expression. (Incidentally, this is something we might have accomplished with a nested function in Object Pascal/Delphi. Nested functions are possible in VB using Reflection. See the article located here: http://www.codeguru.com/columns/vb/article.php/c12749, which is in C# but could easily be converted to VB for an example.) The Lambda Function initializes an array of characters that represent the characters to split the input string on. The StringSplitOptions argument removes empty items, the for loop sets all of the words to lower case and the results are returned. Finally, the Array.ForEach statement uses a Lambda Sub to display the results.

You could of course condense this code quite a bit by converting the Lambda Sub to perform the splitting operation. Of course, doing so would not make the code any easier to understand.

Lambda Expressions at first glance take a little getting used to visually, but they are just (generally) condensed methods that fit into a more complex place. Listing 2 shows a variation that uses a multi-line Lambda Sub inside of the Array.ForEach statement. While there is only one line in the Lambda Sub, multi-line syntax was employed.


Module Module1

   Sub Main()

     Const s As String =
       “The time has come the Walrus said, to talk of many things ” +
       “Of Shoes–Of Ships–Of Sealing Wax–Of cababges and Kings”

     Dim separators As Char() = {Chr(32), “,”, “-“}
     Array.ForEach(s.Split(separators,
       StringSplitOptions.RemoveEmptyEntries),
       Sub(input)
         Console.WriteLine(input.ToLower())
       End Sub)
     Console.ReadLine()

   End Sub
End Module



Listing 2: A little better version using a Lambda Sub with multi-line syntax.

I suspect some programmers may not like the condensed more terse nature of Lambda Expressions and multi-line expressions. However, they are supported by the .NET framework and you will encounter them. It is best to get used to them. Additionally, some very powerful technologies like extension methods and LINQ rely on them and every developer that defers learning how to use these relatively new language features will be at a tactical disadvantage.

Summary

The teams merging seems to represent a stance that VB is not a limited, business application, development language and C# programming is for everything. Both languages sit on top of the most important thing, the .NET framework. As a result you will see more features like automatic properties and full support for Lambda Expressions in VB; that is, you will see a better balance between the two languages placing VB firmly on par with C# as a viable choice for any kind of application development.

Related Articles

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read