{"id":5473,"date":"2007-09-11T22:10:30","date_gmt":"2007-09-11T22:10:30","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/vbteam\/2007\/09\/11\/lambda-expressions-and-expression-trees\/"},"modified":"2024-07-05T14:41:01","modified_gmt":"2024-07-05T21:41:01","slug":"lambda-expressions-and-expression-trees","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/vbteam\/lambda-expressions-and-expression-trees\/","title":{"rendered":"Lambda Expressions and Expression Trees"},"content":{"rendered":"<p>Hi there!<\/p>\n<p>My name is Tim, and I&#8217;m the dev lead for the VB compiler team. Recently Amanda convinced me to blog on the VB team blog rather then <a href=\"http:\/\/blogs.msdn.com\/timng\">my own blog<\/a> for a variety of reasons, and so here I am. My current plan is that I&#8217;ll post VB related postings here, and more compiler implementation\/technology\/fun facts on my own blog (ie, things that don&#8217;t relate to the&nbsp;VB language\/features).<\/p>\n<p>Recently my article on <a href=\"http:\/\/msdn.microsoft.com\/msdnmag\/issues\/07\/09\/BasicInstincts\/\">lambda expressions<\/a> got published on MSDN magazine. For this blog post, I&#8217;m going to expand on some of the ideas in that article, so feel free to check out the article if some of the ideas here don&#8217;t make sense yet.<\/p>\n<p>Lambda expressions are really cool not only because of the reasons stated in the article, but also because it&#8217;s possible to capture the contents of a lambda expression in a readable form and treat it as data rather than executable code.<\/p>\n<p>For example, the following line of code turns a lambda expression into a callable delegate:<\/p>\n<pre class=\"csharpcode\"><span class=\"kwrd\">Dim<\/span> f <span class=\"kwrd\">As<\/span> Func(Of <span class=\"kwrd\">Integer<\/span>, <span class=\"kwrd\">Integer<\/span>) = <span class=\"kwrd\">function<\/span>(x) x * 2\n<span class=\"kwrd\">Dim<\/span> r = f(10)<\/pre>\n<p>.csharpcode, .csharpcode pre\n{\n\tfont-size: small;\n\tcolor: black;\n\tfont-family: consolas, &#8220;Courier New&#8221;, courier, monospace;\n\tbackground-color: #ffffff;\n\t\/*white-space: pre;*\/\n}\n.csharpcode pre { margin: 0em; }\n.csharpcode .rem { color: #008000; }\n.csharpcode .kwrd { color: #0000ff; }\n.csharpcode .str { color: #006080; }\n.csharpcode .op { color: #0000c0; }\n.csharpcode .preproc { color: #cc6633; }\n.csharpcode .asp { background-color: #ffff00; }\n.csharpcode .html { color: #800000; }\n.csharpcode .attr { color: #ff0000; }\n.csharpcode .alt\n{\n\tbackground-color: #f4f4f4;\n\twidth: 100%;\n\tmargin: 0em;\n}\n.csharpcode .lnum { color: #606060; }<\/p>\n<p>In this code sample, the first line creates a lambda expression and does the magic to assign it to&nbsp;a callable delegate&nbsp;f, and the second line invokes f and returns 20.<\/p>\n<p>This is all&nbsp;cool, and I hope my article highlights some of the reasons why I think this is cool. What&#8217;s even more cool is that you can&nbsp;actually assign a lambda expression&nbsp;into a special&nbsp;variable type and the compiler does some more magic for you:<\/p>\n<pre class=\"csharpcode\"><span class=\"kwrd\">Dim<\/span> e <span class=\"kwrd\">As<\/span> Expression(Of Func(Of <span class=\"kwrd\">Integer<\/span>, <span class=\"kwrd\">Integer<\/span>)) = <span class=\"kwrd\">function<\/span>(x) x * 2<\/pre>\n<p>.csharpcode, .csharpcode pre\n{\n\tfont-size: small;\n\tcolor: black;\n\tfont-family: consolas, &#8220;Courier New&#8221;, courier, monospace;\n\tbackground-color: #ffffff;\n\t\/*white-space: pre;*\/\n}\n.csharpcode pre { margin: 0em; }\n.csharpcode .rem { color: #008000; }\n.csharpcode .kwrd { color: #0000ff; }\n.csharpcode .str { color: #006080; }\n.csharpcode .op { color: #0000c0; }\n.csharpcode .preproc { color: #cc6633; }\n.csharpcode .asp { background-color: #ffff00; }\n.csharpcode .html { color: #800000; }\n.csharpcode .attr { color: #ff0000; }\n.csharpcode .alt\n{\n\tbackground-color: #f4f4f4;\n\twidth: 100%;\n\tmargin: 0em;\n}\n.csharpcode .lnum { color: #606060; }<\/p>\n<p>In this code sample, e is not a callable delegate. Rather, it&#8217;s an <strong>expression tree<\/strong>. An expression tree is a data representation of the lambda expression in a form that is easy for you to read and reason about the lambda expression in.<\/p>\n<p>If you look through the value of e in the debugger, you&#8217;ll see that you can easily determine that the expression was a multiplication operation of variable called x of type integer with a constant integer 2.<\/p>\n<p>By default, query operators that extend IEnumerable take lambda expressions. Query operators that extend IQueryable take expression trees. Therefore, when you issue a query over a type that is queryable, the compiler will generate an expression tree rather than a lambda expression.<\/p>\n<p><a href=\"http:\/\/msdn.microsoft.com\/msdnmag\/issues\/07\/08\/BasicInstincts\/\">Scott<\/a>, one of the developers on my team, has written an excellent article as well on some of these ideas. He has a great diagram there showing the expression tree representation of a few lambda expressions.<\/p>\n<p>What can you do with expression trees?<\/p>\n<p>In general, you can do 2 things:<\/p>\n<ol>\n<li>Reason about the data in the expression tree, and do custom processing over it. You can also convert the data in the expression tree into another domain (such as XML).\n<li>Use the .Compile() method to turn the expression tree into a delegate so that you can execute it.\n<li>Build queries with dynamic conditions: see <a href=\"http:\/\/blogs.msdn.com\/vbteam\/archive\/2007\/08\/29\/implementing-dynamic-searching-using-linq.aspx\">Jonathan&#8217;s<\/a> (our PM) excellent post. He has a great example of how you can manipulate the expression trees and build custom conditions in your lambda expressions.<\/li>\n<\/ol>\n<p>Item 2 is interesting, because it means that you can write a lambda expression into an expression tree, reason about it,&nbsp;etc, and then turn it into a callable delegate.<\/p>\n<pre class=\"csharpcode\"><span class=\"kwrd\">Dim<\/span> e <span class=\"kwrd\">As<\/span> Expression(Of Func(Of <span class=\"kwrd\">Integer<\/span>, <span class=\"kwrd\">Integer<\/span>)) = <span class=\"kwrd\">function<\/span>(x) x * 2\n<span class=\"kwrd\">Dim<\/span> f = e.Compile\n<span class=\"kwrd\">Dim<\/span> r = f(10)<\/pre>\n<p>In this example, the value of r is 20, just like the previous example where we assigned the lambda directly to a delegate type.\n.csharpcode, .csharpcode pre\n{\n\tfont-size: small;\n\tcolor: black;\n\tfont-family: consolas, &#8220;Courier New&#8221;, courier, monospace;\n\tbackground-color: #ffffff;\n\t\/*white-space: pre;*\/\n}\n.csharpcode pre { margin: 0em; }\n.csharpcode .rem { color: #008000; }\n.csharpcode .kwrd { color: #0000ff; }\n.csharpcode .str { color: #006080; }\n.csharpcode .op { color: #0000c0; }\n.csharpcode .preproc { color: #cc6633; }\n.csharpcode .asp { background-color: #ffff00; }\n.csharpcode .html { color: #800000; }\n.csharpcode .attr { color: #ff0000; }\n.csharpcode .alt\n{\n\tbackground-color: #f4f4f4;\n\twidth: 100%;\n\tmargin: 0em;\n}\n.csharpcode .lnum { color: #606060; }\n<\/p>\n<p>Why is this interesting?<\/p>\n<p>Without expression trees, its impossible to describe expressions in a descriptive format; the only description of them is IL, which is too low level to re-create the user&#8217;s intent for the expression. Rather, expression trees provide a high level tree representation of an expression, so that you can easily understand the user&#8217;s intent for the expression.<\/p>\n<p>Here are some uses of expression trees that may be interesting:<\/p>\n<ol>\n<li>Reason about expressions, then convert them to delegates and call them.\n<li>Convert expressions into SQL so that they can be executed by a server (this is what LINQ to SQL does).\n<li>Convert expressions into XML and write them to disk.\n<li>Convert expressions into a custom format to send over a network protocol to a server that can then rebuild the expression tree from the format, recreate the expression, and reason about it and\/or execute it.<\/li>\n<\/ol>\n<p>Over the next several posts, I&#8217;m going to blog specifically about the expression trees that the VB compiler generates, and some differences between C# trees and VB trees in order to maintain VB semantics. I will also provide tips on things you can do to be sure that any library that you write that consumes expression trees will provide the best experience for VB developers.<\/p>\n<p>Tim<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hi there! My name is Tim, and I&#8217;m the dev lead for the VB compiler team. Recently Amanda convinced me to blog on the VB team blog rather then my own blog for a variety of reasons, and so here I am. My current plan is that I&#8217;ll post VB related postings here, and more [&hellip;]<\/p>\n","protected":false},"author":260,"featured_media":8818,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[21,195],"tags":[77,94,154],"class_list":["post-5473","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-im-a-vb","category-visual-basic","tag-iqueryable","tag-linqvb9","tag-timothy-ng"],"acf":[],"blog_post_summary":"<p>Hi there! My name is Tim, and I&#8217;m the dev lead for the VB compiler team. Recently Amanda convinced me to blog on the VB team blog rather then my own blog for a variety of reasons, and so here I am. My current plan is that I&#8217;ll post VB related postings here, and more [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts\/5473","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/users\/260"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/comments?post=5473"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts\/5473\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/media\/8818"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/media?parent=5473"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/categories?post=5473"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/tags?post=5473"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}