<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Fabulous Adventures In Coding : Lambda Expressions</title><link>http://blogs.msdn.com/ericlippert/archive/tags/Lambda+Expressions/default.aspx</link><description>Tags: Lambda Expressions</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Closing over the loop variable, part two</title><link>http://blogs.msdn.com/ericlippert/archive/2009/11/16/closing-over-the-loop-variable-part-two.aspx</link><pubDate>Mon, 16 Nov 2009 16:18:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9923025</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>42</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9923025.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9923025</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;Thanks to everyone who left thoughtful and insightful comments on last week's post.&lt;/P&gt;
&lt;P&gt;More countries&amp;nbsp;really ought to implement Instant Runoff Voting; it would certainly appeal to the geek crowd. Many people left complex opinions of the form "I'd prefer to make the change, but if you can't do that then make it a warning". Or "don't make the change, do make it a warning", and so on.&amp;nbsp;But what I can deduce from reading the comments is that there is a general lack of consensus on what the right thing to do here is. In fact, I just did a quick tally:&lt;/P&gt;
&lt;P&gt;Commenters who expressed support for a warning: 26&lt;BR&gt;Commenters who expressed the sentiment "it's better to not make the change": 24&lt;BR&gt;Commenters who expressed the sentiment "it's better to make the change": 25&lt;/P&gt;
&lt;P&gt;Wow. I guess we'll flip a coin. :-)&amp;nbsp;&amp;nbsp;&amp;nbsp; (*)&lt;/P&gt;
&lt;P&gt;Four people suggested to actually make it an error to do this. That's a pretty big breaking change, particularly since we would be breaking not just "already broken" code, but plenty of code that works perfectly well today -- see below. That's not likely to happen.&lt;/P&gt;
&lt;P&gt;People also left a number of interesting suggestions. I thought I'd discuss some of those a little bit.&lt;/P&gt;
&lt;P&gt;First off, I want to emphasize that what we're attempting to address here is the problem that &lt;STRONG&gt;the language encourages people to write code that has different semantics than they think it has&lt;/STRONG&gt;. The problem is NOT that the language has no way to express the desired semantics; clearly it does. Just introduce a new variable explicitly into the loop.&lt;/P&gt;
&lt;P&gt;A number of suggestions were for ways that the language could more elegantly express that notion. Some of the suggestions:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;foreach(var x in c) &lt;STRONG&gt;inner&lt;/STRONG&gt; &lt;BR&gt;&lt;STRONG&gt;foreachnew&lt;/STRONG&gt;(var x in c)&lt;BR&gt;foreach(&lt;STRONG&gt;new&lt;/STRONG&gt; var x in c)&lt;BR&gt;foreach(var x&amp;nbsp;&lt;STRONG&gt;from&lt;/STRONG&gt; c) &lt;BR&gt;foreach(var x&amp;nbsp;&lt;STRONG&gt;inside&lt;/STRONG&gt; c) &lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Though we could do any of those, none of them by themselves solve the problem at hand. Today, you have to know to use a particular pattern with foreach to get the semantics you want: declare a variable inside the loop. With one of these changes, you still have to know to use a particular keyword to get the semantics you want, and it is still easy to accidentally do the wrong thing. &lt;/P&gt;
&lt;P&gt;Furthermore,&amp;nbsp;a change so small and so targetted at such a narrow scenario probably does not provide enough benefit to justify the large cost of creating a new syntax, particularly one which is still easily confused with an existing syntax.&lt;/P&gt;
&lt;P&gt;C++ luminary Herb Sutter happened to be in town and was kind enough to stop by my office to describe to me how they are solving a related problem in C++. Apparently the next version of the C++ standard will include lambdas, and they're doing this:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;&lt;EM&gt;[q, &amp;amp;r]&lt;/EM&gt; &lt;STRONG&gt;(int x) -&amp;gt; int&lt;/STRONG&gt; { return M(x, q, r); }&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;This means that the lambda captures outer variable q by value, captures r by reference, takes an int and returns an int. Whether the lambda captures values or references is controllable! An interesting approach but one that doesn't immediately solve our problem here; we cannot make lambdas capture by value by default without a huge breaking change. Capturing by value would have to require new syntax, and then we're in the same boat again: the user has to know to use the new syntax when in a foreach loop.&lt;/P&gt;
&lt;P&gt;A number of people also asked what the down sides of adding a warning are. The down side is that &lt;STRONG&gt;a warning which warns about correct behaviour is a very bad warning&lt;/STRONG&gt;; it makes people change working code, and frequently they break working code in order to eliminate a warning that shouldn't have been present in the first place. Consider:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;foreach(var insect in insects)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; var query = frogs.Where(frog=&amp;gt;frog.Eats(insect));&lt;BR&gt;&amp;nbsp; Console.WriteLine("{0} is eaten by {1} frogs.", insect, query.Count());&lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;This makes a lambda closed over insect; the lambda never escapes the loop, so there's no problem here. But the compiler doesn't know that. The compiler sees that the lambda is being passed to a method called Where, and Where is allowed to do anything with that delegate, including storing it away to be called later. Which is exactly what Where does! Where stores away the lambda into a monad that represents the execution of the query. The fact that the &lt;STRONG&gt;query object doesn't survive the loop&lt;/STRONG&gt; is what keeps this safe. But how is the compiler supposed to suss out that tortuous chain of reasoning? We'd have to give a warning for this case, even though it is perfectly safe. &lt;/P&gt;
&lt;P&gt;It gets worse. A lot of people are required by their organizations to compile with "warnings are errors" turned on. Therefore, any time we introduce a new warning for a pattern that is often actually safe and frequently used, we are effectively causing an enormous breaking change. A vaccine which kills more healthy people than the disease would have is probably not a good bet. (**)&lt;/P&gt;
&lt;P&gt;This is not to say that a warning is a bad idea, but that it is not the obvious slam dunk good idea that it initially appears to be.&lt;/P&gt;
&lt;P&gt;A number of people suggested that the problem was in the training of the developers, not in the design of the language. I disagree. Obviously modern languages are complex tools that require training to use, but we are working hard to make a language where people's natural intuitions about how things work lead them to write correct code. I have myself made this error a number of times, usually in the form of writing code like the code above, and then refactoring it in such a manner that suddenly some part of it escapes the loop and the bug is introduced. It is very easy to make this mistake, even for experienced developers who thoroughly understand closure semantics. That's a flaw in the design of the language. &lt;/P&gt;
&lt;P&gt;And finally, a number of people made suggestions of the form "make it a warning in C# 4, and an error in C# 5", or some such thing. FYI, C# 4 is DONE. We are only making a few last-minute "user is electrocuted"-grade bug fixes, mostly based on your excellent feedback from the betas. (If you have bug reports from the beta, please keep sending them, but odds are good they won't get fixed for the initial release.) We are certainly not capable of introducing any sort of major design change or new feature at this point. And we try to not introduce semantic changes or new features in service packs. We're going to have to live with this problem for at least another cycle, unfortunately.&lt;/P&gt;
&lt;P&gt;********&lt;/P&gt;
&lt;P&gt;(*) Mr. Smiley Face indicates that Eric is indulging in humourous japery.&lt;/P&gt;
&lt;P&gt;(**) I wish to emphasize that I am 100% in favour of vaccinations for deadly infectious&amp;nbsp;diseases, &lt;EM&gt;even vaccines that are potentially dangerous&lt;/EM&gt;. The number of people made ill or killed by the smallpox vaccine was tiny compared to the number of people who did not contract this deadly, contagious (and now effectively extinct)&amp;nbsp;disease as a result of mass vaccination. I am a strong supporter of vaccine research. I'm just making an analogy here people.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9923025" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Breaking+Changes/default.aspx">Breaking Changes</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Lambda+Expressions/default.aspx">Lambda Expressions</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/foreach/default.aspx">foreach</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/closures/default.aspx">closures</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/coin+flipping/default.aspx">coin flipping</category></item><item><title>Closing over the loop variable considered harmful</title><link>http://blogs.msdn.com/ericlippert/archive/2009/11/12/closing-over-the-loop-variable-considered-harmful.aspx</link><pubDate>Thu, 12 Nov 2009 14:50:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9918689</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>123</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9918689.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9918689</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;I don't know why I haven't blogged about this one before; this is the single most common incorrect bug report we get. That is, someone thinks they have found a bug&amp;nbsp;in the compiler, but in fact the compiler is correct and their code is wrong. That's a terrible situation for everyone; we very much wish to design a language which does not have "gotcha" features like this. &lt;/P&gt;
&lt;P&gt;But I'm getting ahead of myself. What's the output of this fragment?&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;var&amp;nbsp;values = new List&amp;lt;int&amp;gt;() { 100, 110, 120 };&lt;BR&gt;var&amp;nbsp;funcs = new List&amp;lt;Func&amp;lt;int&amp;gt;&amp;gt;();&lt;BR&gt;foreach(var v in values) &lt;BR&gt;&amp;nbsp; funcs.Add( ()=&amp;gt;v );&lt;BR&gt;foreach(var f&amp;nbsp;in funcs) &lt;BR&gt;&amp;nbsp; Console.WriteLine(f());&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Most people expect it to be 100 / 110 / 120.&amp;nbsp; It is in fact 120 / 120 / 120. Why?&lt;/P&gt;
&lt;P&gt;Because &lt;SPAN class=code&gt;()=&amp;gt;v&lt;/SPAN&gt; means "return &lt;STRONG&gt;the current value of variable v&lt;/STRONG&gt;", not "return the value v was back when the delegate was created". &lt;STRONG&gt;Closures close over variables, not over values.&lt;/STRONG&gt; And when the methods run, clearly the last value that was assigned to v was 120, so it still has that value.&lt;/P&gt;
&lt;P&gt;This is very confusing. The correct way to write the code is:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;foreach(var v in values) &lt;BR&gt;{&lt;BR&gt;&amp;nbsp; var v2 = v;&lt;BR&gt;&amp;nbsp; funcs.Add( ()=&amp;gt;v2 );&lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Now what happens? Every time we re-start the loop body, we logically create a fresh new variable v2. Each closure is closed over a different v2, which is only assigned to once, so it always keeps the correct value. &lt;/P&gt;
&lt;P&gt;Basically, the problem arises because we specify that the foreach loop is a syntactic sugar for&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;&amp;nbsp; {&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IEnumerator&amp;lt;int&amp;gt; e = ((IEnumerable&amp;lt;int&amp;gt;)values).GetEnumerator();&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; try&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int m; // OUTSIDE THE ACTUAL LOOP&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; while(e.MoveNext())&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m = (int)(int)e.Current;&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;funcs.Add(()=&amp;gt;m);&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; finally&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (e != null) ((IDisposable)e).Dispose();&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR minmax_bound="true"&gt;&amp;nbsp; }&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;If we specified that the expansion was&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; try&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; while(e.MoveNext())&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int m; // INSIDE&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m = (int)(int)e.Current;&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;funcs.Add(()=&amp;gt;m);&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;then the code would behave as expected.&lt;/P&gt;
&lt;P&gt;It's compelling to consider fixing this for a hypothetical future version of C#, and I'd like to hear your feedback on whether we should do so or not. The reasons FOR making the change are clear; this is a big confusing "gotcha" that real people constantly run into, and LINQ, unfortunately, only makes it worse, because it is likely to increase the number of times&amp;nbsp;a customer is going to use a closure in a loop. Also, it seems reasonable that the user of the&amp;nbsp;foreach loop&amp;nbsp;might&amp;nbsp;think of&amp;nbsp;there being&amp;nbsp;a "fresh" loop variable every time, not just a fresh value in the same old variable. Since the foreach loop variable is not mutable by user code, this reinforces the idea that it is a succession of values, one per loop iteration, and not "really" the same variable over and over again. And finally, the change has no effect whatsoever on non-closure semantics. (In fact, in C# 1 the spec was not clear about whether the loop variable went inside or outside, since in a world without closures, it makes no difference.)&lt;/P&gt;
&lt;P&gt;But that said, there are some very good reasons for not making this change.&lt;/P&gt;
&lt;P&gt;The first reason is that obviously this would be a breaking change, and we hates them, my precious. Any developers who depend on this feature, who require the closed-over variable to contain the last value of the loop variable, would be broken. I can only hope that the number of such people is vanishingly small; this is a strange thing to depend on. Most of the time, people do not expect or depend on this behaviour.&lt;/P&gt;
&lt;P&gt;Second, it makes the foreach syntax lexically inconsistent. Consider &lt;SPAN class=code&gt;foreach(int x in M())&lt;/SPAN&gt; The header of the loop has two parts, a declaration &lt;SPAN class=code&gt;int x&lt;/SPAN&gt; and a collection expression, &lt;SPAN class=code&gt;M()&lt;/SPAN&gt;. The &lt;SPAN class=code&gt;int x&lt;/SPAN&gt; is to the left of the &lt;SPAN class=code&gt;M()&lt;/SPAN&gt;. Clearly the &lt;SPAN class=code&gt;M()&lt;/SPAN&gt; is not inside the body of the loop; that thing only executes once, before the loop starts. So &lt;EM&gt;why should something to the collection expression's left be inside the loop&lt;/EM&gt;? This seems inconsistent with our general rule that stuff to the left logically "happens before" stuff to the right. The declaration is lexically NOT in the body of the loop, so why should we treat it as though it were?&lt;/P&gt;
&lt;P&gt;Third, it would make the "foreach" semantics inconsistent with "for" semantics. We have this same problem in "for" blocks, but "for" blocks are much looser about what "the loop variable" is; there can be more than one variable declared in the for loop header, it can be incremented in odd ways, and it seems implausible that people would consider each iteration of the "for" loop to contain a fresh crop of variables. When you say &lt;SPAN class=code&gt;for(int i; i &amp;lt; 10; i += 1)&lt;/SPAN&gt; it seems dead obvious that the "i += 1" means "increment the loop variable" and that there is one loop variable for the whole loop, not a new fresh variable "i" every time through! We certainly would not make this proposed change apply to "for" loops.&lt;/P&gt;
&lt;P&gt;And fourth, though this is a nasty gotcha, there is an easy workaround, and tools like ReSharper detect this pattern and suggest how to fix it. We could take a page from that playbook and simply&amp;nbsp;issue a compiler warning on this pattern. (Though adding new warnings brings up a whole raft of issues of&amp;nbsp;its own, which I might get into in another post.)&amp;nbsp;Though this is vexing, it really doesn't bite that many people that hard, and it's not a big deal to fix, so why go to the trouble and expense of taking a breaking change for something with an easy fix?&lt;/P&gt;
&lt;P&gt;Design is, of course, the art of compromise in the face of many competing principles. "Eliminate gotchas" in this case directly opposes other principles like "no breaking changes", and "be consistent with other language features". Any thoughts you have on pros or cons of us taking this breaking change in a hypothetical future version of C# would be greatly appreciated. &lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9918689" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Breaking+Changes/default.aspx">Breaking Changes</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Lambda+Expressions/default.aspx">Lambda Expressions</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Language+Design/default.aspx">Language Design</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/foreach/default.aspx">foreach</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/closures/default.aspx">closures</category></item><item><title>Iterator Blocks Part Seven: Why no anonymous iterators?</title><link>http://blogs.msdn.com/ericlippert/archive/2009/08/24/iterator-blocks-part-seven-why-no-anonymous-iterators.aspx</link><pubDate>Mon, 24 Aug 2009 16:23:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9872415</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>21</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9872415.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9872415</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;This annotation to a comment in part five I think deserves to be promoted to a post of its own. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Why do we disallow anonymous iterators?&lt;/STRONG&gt; I would love to have anonymous iterator blocks.&amp;nbsp; I want to say something like:&lt;/P&gt;
&lt;P&gt;&lt;SPAN class=code&gt;IEnumerable&amp;lt;int&amp;gt; twoints = ()=&amp;gt;{ yield return x; yield return x*10; }; &lt;BR&gt;foreach(int i in twoints) ... &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;It would be totally awesome to be able to build yourself a little sequence generator in-place that closed over local variables. The reason why not is straightforward: the benefits don't outweigh the costs. The awesomeness of making sequence generators in-place is actually pretty small in the grand scheme of things and nominal methods do the job well enough in most scenarios. So the benefits are not that compelling. &lt;/P&gt;
&lt;P&gt;The costs are large. Iterator rewriting is the most complicated transformation in the compiler, and anonymous method rewriting is the second most complicated. Anonymous methods can be inside other anonymous methods, and anonymous methods can be inside iterator blocks. Therefore, what we do is first we rewrite all anonymous methods so that they become methods of a closure class. This is the second-last thing the compiler does before emitting IL for a method. Once that step is done, the iterator rewriter can assume that there are no anonymous methods in the iterator block; they've all be rewritten already. Therefore the iterator rewriter can just concentrate on rewriting the iterator, without worrying that there might be an unrealized anonymous method in there. &lt;/P&gt;
&lt;P&gt;Also, iterator blocks never "nest", unlike anonymous methods. The iterator rewriter can assume that all iterator blocks are "top level".&lt;/P&gt;
&lt;P&gt;If anonymous methods are allowed to contain iterator blocks, then both those assumptions go out the window. You can have an iterator block that contains an anonymous method that contains an anonymous method that contains an iterator block that contains an anonymous method, and... yuck. Now we have to write a rewriting pass that can handle nested iterator blocks and nested anonymous methods at the same time, merging our two most complicated algorithms into one far more complicated algorithm. It would be really hard to design, implement, and test. We are smart enough to do so, I'm sure. We've got a smart team here. But we don't want to take on that large burden for a "nice to have but not necessary" feature.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9872415" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Lambda+Expressions/default.aspx">Lambda Expressions</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Language+Design/default.aspx">Language Design</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Iterators/default.aspx">Iterators</category></item><item><title>Mmm, Curry</title><link>http://blogs.msdn.com/ericlippert/archive/2009/06/25/mmm-curry.aspx</link><pubDate>Thu, 25 Jun 2009 16:51:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9753677</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>9</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9753677.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9753677</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;A recent comment asked why Haskell programmers sometimes write C# lambdas in this style: &lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;Func&amp;lt;int, Func&amp;lt;int, int&amp;gt;&amp;gt; add = x=&amp;gt;y=&amp;gt;x+y;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;which is then invoked as &lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;sum = add(2)(3);&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;because of course the first invocation returns a function that adds two, which is then invoked with three. Why do that instead of the more straightforward&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;Func&amp;lt;int, int, int&amp;gt; add = (x,y)=&amp;gt;x+y;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;and invoke it as&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;sum = add(2,3);&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;???&lt;/P&gt;
&lt;P&gt;I was going to write a short article on that when I remembered that Wes already had done a better job at it than I likely would. &lt;A href="http://blogs.msdn.com/wesdyer/archive/2007/01/29/currying-and-partial-function-application.aspx" mce_href="http://blogs.msdn.com/wesdyer/archive/2007/01/29/currying-and-partial-function-application.aspx"&gt;Read this first before you read on.&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Welcome back. I would add to that two interesting facts. &lt;/P&gt;
&lt;P&gt;First, that the operation of rewriting an n-parameter function as a bunch of single-parameter functions to achieve “partial application” is called “currying” in honor of Haskell Curry, the logician after whom the programming languages Haskell and Curry are named. &lt;/P&gt;
&lt;P&gt;And second, that it is a little-known fact that there is an ugly but&amp;nbsp;sometimes useful&amp;nbsp;way to “curry away” the first parameter of an existing function using reflection.&lt;/P&gt;
&lt;P&gt;For example, suppose you've got &lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;public class C { &lt;BR&gt;&amp;nbsp; public static int M(T t, int x) { whatever } &lt;BR&gt;} &lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;In C#, to curry away the first parameter you could simply say&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;T t = something;&lt;BR&gt;Func&amp;lt;int, int&amp;gt; d = x=&amp;gt;C.M(t, x);&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Which is of course a syntactic sugar for creating a hidden nested class with a field t and a method that takes an int, blah blah blah, lots of boring code spit out to do that.&lt;/P&gt;
&lt;P&gt;If you need to curry away the first parameter of a method and are using some managed language that does not have anonymous functions, or you are writing a compiler but you don’t feel like spitting a whole bunch of helper methods like the C# compiler does, you can also do this directly with reflection:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;T t = something;&lt;BR&gt;MethodInfo methodInfo = typeof(C).GetMethod("M", BindingFlags.Static | BindingFlags.Public);&lt;BR&gt;Func&amp;lt;int, int&amp;gt; d = (Func&amp;lt;int, int&amp;gt;) Delegate.CreateDelegate(typeof(Func&amp;lt;int, int&amp;gt;), t, methodInfo); &lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;This works in the .NET framework 2.0 release or higher, and, unfortunately, &lt;STRONG&gt;requires that T be a reference type. &lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Notice that this kind of currying is essentially the same currying that happens when you make an extension method into a delegate. If static method C.M is an extension method&amp;nbsp;extending type T then in C# you can say&lt;/P&gt;
&lt;P&gt;Func&amp;lt;int, int&amp;gt; d = t.M;&lt;/P&gt;
&lt;P&gt;and we essentially curry away the first argument to the extension method when creating the delegate, using tricks similar to the reflection trick. (We pass the managed address of the extension method to a constructor rather than passing the method info to the factory, but, basically its the same thing behind the scenes.) If you try this on an extension of a value type, &lt;A class="" href="http://stackoverflow.com/questions/1016033/extension-methods-defined-on-value-types-cannot-be-used-to-create-delegates-why" mce_href="http://stackoverflow.com/questions/1016033/extension-methods-defined-on-value-types-cannot-be-used-to-create-delegates-why"&gt;you'll get an error&lt;/A&gt;. Sree has just posted &lt;A class="" href="http://blogs.msdn.com/sreekarc/archive/2009/06/25/why-can-t-extension-methods-on-value-type-be-curried.aspx" mce_href="http://blogs.msdn.com/sreekarc/archive/2009/06/25/why-can-t-extension-methods-on-value-type-be-curried.aspx"&gt;an analysis of why this has to be a reference type&lt;/A&gt;.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9753677" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Lambda+Expressions/default.aspx">Lambda Expressions</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Functional+Programming/default.aspx">Functional Programming</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Currying/default.aspx">Currying</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Haskell/default.aspx">Haskell</category></item><item><title>The Stack Is An Implementation Detail, Part One</title><link>http://blogs.msdn.com/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx</link><pubDate>Mon, 27 Apr 2009 16:15:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9549311</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>35</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9549311.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9549311</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/ericlippert/WindowsLiveWriter/TheStackIsAnImplementationDetail_C978/Stack_4.jpg" mce_href="http://blogs.msdn.com/blogfiles/ericlippert/WindowsLiveWriter/TheStackIsAnImplementationDetail_C978/Stack_4.jpg"&gt;&lt;IMG title="Stack&lt;Stone&gt;" style="BORDER-TOP-WIDTH: 0px; DISPLAY: inline; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; MARGIN-LEFT: 0px; MARGIN-RIGHT: 0px; BORDER-RIGHT-WIDTH: 0px" height=240 alt="Stack&lt;Stone&gt;" src="http://blogs.msdn.com/blogfiles/ericlippert/WindowsLiveWriter/TheStackIsAnImplementationDetail_C978/Stack_thumb_1.jpg" width=156 align=left border=0 mce_src="http://blogs.msdn.com/blogfiles/ericlippert/WindowsLiveWriter/TheStackIsAnImplementationDetail_C978/Stack_thumb_1.jpg"&gt;&lt;/A&gt;I blogged a while back about how &lt;A href="http://blogs.msdn.com/ericlippert/archive/2009/02/17/references-are-not-addresses.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2009/02/17/references-are-not-addresses.aspx"&gt;“references” are often described as “addresses”&lt;/A&gt; when describing the semantics of the C# memory model. Though that’s arguably &lt;EM&gt;correct&lt;/EM&gt;, it’s also arguably an &lt;EM&gt;implementation detail&lt;/EM&gt; rather than an important eternal truth. Another memory-model implementation detail I often see presented as a fact is “value types are allocated on the stack”. I often see it because of course, &lt;A href="http://msdn.microsoft.com/en-us/library/system.valuetype.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.valuetype.aspx"&gt;that’s what our documentation says&lt;/A&gt;. &lt;/P&gt;
&lt;P&gt;Almost every article I see that describes the difference between value types and reference types explains in (frequently incorrect) detail about what “the stack” is and how the major difference between value types and reference types is that value types go on the stack. I’m sure you can find dozens of examples by searching the web.&lt;/P&gt;
&lt;P&gt;I find this characterization of a value type based on its &lt;EM&gt;implementation details&lt;/EM&gt; rather than its &lt;EM&gt;observable characteristics&lt;/EM&gt; to be both confusing and unfortunate. Surely the most relevant fact about value types is not the implementation detail of &lt;EM&gt;how they are allocated&lt;/EM&gt;, but rather the &lt;EM&gt;by-design semantic meaning&lt;/EM&gt; of “value type”, namely &lt;EM&gt;that they are always copied “by value”&lt;/EM&gt;. If the relevant thing was their allocation details then we’d have called them “heap types” and “stack types”. But that’s not relevant most of the time. Most of the time the relevant thing is their copying and identity semantics.&lt;/P&gt;
&lt;P&gt;I regret that the documentation does not focus on what is most relevant; by focusing on a largely irrelevant implementation detail, we enlarge the importance of that implementation detail and obscure the importance of what makes a value type semantically useful. I dearly wish that all those articles explaining what “the stack” is would instead spend time explaining what exactly “copied by value” means and how misunderstanding or misusing “copy by value” can cause bugs.&lt;/P&gt;
&lt;P&gt;Of course, the simplistic statement I described is not even &lt;EM&gt;true&lt;/EM&gt;. As the MSDN documentation correctly notes, value types are allocated on the stack &lt;EM&gt;sometimes&lt;/EM&gt;. For example, the memory for an integer field in a class type is part of the class instance’s memory, which is allocated on the heap. A local variable is hoisted to be implemented as a field of a hidden class if the local is an outer variable used by an anonymous method(*) so again, the storage associated with that local variable will be on the heap if it is of value type.&lt;/P&gt;
&lt;P&gt;But more generally, again we have &lt;STRONG&gt;an explanation that doesn’t actually explain anything&lt;/STRONG&gt;. Leaving performance considerations aside, what possible difference does it make &lt;EM&gt;to the developer&lt;/EM&gt; whether the CLR’s jitter happens to allocate memory for a particular local variable by adding some integer to the pointer that we call “the stack pointer” or adding the same integer to the pointer that we call “the top of the GC heap”? As long as the implementation maintains the semantics guaranteed by the specification, it can choose any strategy it likes for generating efficient code. &lt;/P&gt;
&lt;P&gt;Heck, there’s no requirement that the &lt;EM&gt;operating system&lt;/EM&gt; that the CLI is implemented on top of provide a per-thread one-meg array called “the stack”. That Windows typically does so, and that this one-meg array is an efficient place to store small amounts of short-lived data is great, but it’s not a requirement that an operating system provide such a structure, or that the jitter use it. The jitter could choose to put every local “on the heap” and live with the performance cost of doing so, as long as the value type semantics were maintained.&lt;/P&gt;
&lt;P&gt;Even worse though is the frequently-seen characterization that value types are “small and fast” and reference types are “big and slow”. Indeed, value types that can be jitted to code that allocates off the stack are extremely fast to both allocate and deallocate. Large structures heap-allocated structures like arrays of value type are also pretty fast, particularly if you need them initialized to the default state of the value type. And there is some memory overhead to ref types. And there are some high-profile cases where value types give a big perf win. &lt;STRONG&gt;But in the vast majority of programs out there, local variable allocations and deallocations are not going to be the performance bottleneck.&lt;/STRONG&gt; &lt;/P&gt;
&lt;P&gt;Making the nano-optimization of making a type that really should be a ref type into a value type for a few nanoseconds of perf gain is probably not worth it. I would only be making that choice if profiling data showed that there was a large, real-world-customer-impacting performance problem directly mitigated by using value types. Absent such data, I’d always make the choice of value type vs reference type based on whether the type is &lt;EM&gt;semantically&lt;/EM&gt; representing a value or &lt;EM&gt;semantically&lt;/EM&gt; a reference to something.&lt;/P&gt;
&lt;P&gt;UPDATE: &lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2009/05/04/the-stack-is-an-implementation-detail-part-two.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2009/05/04/the-stack-is-an-implementation-detail-part-two.aspx"&gt;Part two is here&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;*******&lt;/P&gt;
&lt;P&gt;(*) Or in an iterator block.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9549311" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Performance/default.aspx">Performance</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Lambda+Expressions/default.aspx">Lambda Expressions</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Code+Generation/default.aspx">Code Generation</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Memory+Management/default.aspx">Memory Management</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Value+Types/default.aspx">Value Types</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/myths/default.aspx">myths</category></item><item><title>Five-Dollar Words For Programmers, Part Three: Homoiconic</title><link>http://blogs.msdn.com/ericlippert/archive/2009/03/23/five-dollar-words-for-programmers-part-three-homoiconic.aspx</link><pubDate>Mon, 23 Mar 2009 23:33:42 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9502480</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>24</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9502480.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9502480</wfw:commentRss><description>&lt;div class="mine"&gt; &lt;p&gt;Jeff Atwood was kind enough to once more &lt;a href="http://www.codinghorror.com/blog/archives/001244.html"&gt;give me the shout-out in his blog the other day&lt;/a&gt;. Thanks Jeff!&lt;/p&gt; &lt;p&gt;This inspires me to continue my series on five-dollar words for programmers. Here’s one that I only learned relatively recently, when I helped write the code that translates a lambda expression into an expression tree which represents the content of the lambda: &lt;strong&gt;&lt;a href="http://en.wikipedia.org/wiki/Homoiconic"&gt;homoiconic&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt; &lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/bb397951.aspx"&gt;&lt;img title="Expression Trees" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; margin: 0px 10px 0px 0px; border-right-width: 0px" height="240" alt="Expression Trees" src="http://blogs.msdn.com/blogfiles/ericlippert/WindowsLiveWriter/FiveDollarWordsForProgrammersPartThreeHo_BE81/Expression%20Trees_3.png" width="260" align="left" border="0"&gt;&lt;/a&gt; A language is said to be &lt;strong&gt;homoiconic&lt;/strong&gt; if the &lt;strong&gt;representation&lt;/strong&gt; of the program can be seen as a &lt;strong&gt;data structure&lt;/strong&gt; expressible in that language. With expression lambdas being convertible to expression trees (which can then be compiled into code at runtime), C# 3.0 is &lt;em&gt;somewhat&lt;/em&gt; homoiconic. But it pales in comparison to, say, LISP, where pretty much everything you can do in the language you can also represent as structurally isomophic data.&lt;/p&gt; &lt;p&gt;Something I personally would like to see more of in C# in the future is greater homoiconicity. We could extend expression trees to statement trees, declaration trees, program trees, and so on. This series of steps would enable increasingly powerful and interesting &lt;strong&gt;metaprogramming scenarios&lt;/strong&gt;. &lt;/p&gt; &lt;p&gt;C# suffers from the lack of a metalanguage. We absolutely do not want to go towards the horrible and primitive metaprogramming language exemplified by the C preprocessor language. We already have a great language, C#, so why not use C# as a metalanguage? Wouldn’t it be nice to &lt;strong&gt;make C# its own metalanguage&lt;/strong&gt;? And once we do that, then we get into some truly strange loops, where we could use those data structures in the compiler implementation itself!&lt;/p&gt; &lt;p&gt;This is a long way off and might never happen, but a guy can dream.&lt;/p&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9502480" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Rarefied+Heights/default.aspx">Rarefied Heights</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Lambda+Expressions/default.aspx">Lambda Expressions</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Big+Words/default.aspx">Big Words</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Language+Design/default.aspx">Language Design</category></item><item><title>Method Type Inference Changes, Part One</title><link>http://blogs.msdn.com/ericlippert/archive/2008/06/17/method-type-inference-changes-part-one.aspx</link><pubDate>Tue, 17 Jun 2008 18:20:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8611835</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>9</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/8611835.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=8611835</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;I want to start this by discussing the purpose of method type inference, and clearing up some potential misunderstandings about type inference errors.&lt;/P&gt;
&lt;P&gt;First off though, a brief note on nomenclature. Throughout this series when I say "type inference" I mean "method type inference", not any of the other forms of type inference we have in C# 3.0. (Implicitly typed locals, implicitly typed arrays, and so on.)&lt;/P&gt;
&lt;P&gt;The purpose of type inference is to allow generic methods to be called without explicitly specifying the generic types. For example, if you have a generic method&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;static&amp;nbsp;T Largest&amp;lt;T&amp;gt;(IEnumerable&amp;lt;T&amp;gt; list) where T : IComparable&amp;lt;T&amp;gt; { ... }&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;then it would be nice to be able to say&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;decimal&amp;nbsp;maxPrice = Largest(prices);&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;without having to say redundant information:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;decimal&amp;nbsp;maxPrice = Largest&amp;lt;decimal&amp;gt;(prices);&lt;/P&gt;&lt;/SPAN&gt;
&lt;P mce_keep="true"&gt;This was useful in C# 2.0, but with the advent of extension methods and query comprehensions in C# 3.0, it is downright vital. If we made Largest into an extension method then clearly you want to be able to say&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P mce_keep="true"&gt;from customer in customers &lt;BR&gt;from invoices in customers.invoices&lt;BR&gt;select invoices.prices.Largest();&lt;/P&gt;&lt;/SPAN&gt;
&lt;P mce_keep="true"&gt;and not have to insert this ugly mechanism information into your lovely semantic query:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P mce_keep="true"&gt;from customer in customers &lt;BR&gt;from invoices in customers.invoices&lt;BR&gt;select invoices.prices.Largest&amp;lt;decimal&amp;gt;();&lt;/P&gt;&lt;/SPAN&gt;
&lt;P mce_keep="true"&gt;When you call a method without an explicit argument list, overload resolution must figure out which method you meant to call. The way type inference works with overload resolution is that all methods of that name are put into a pool called the candidate set. If any of them are generic, we run a type inference algorithm to see if the generic type arguments can be inferred for the method. If they can, then the constructed generic method stays in the candidate set; if inference fails then it is removed. Then all methods which are inapplicable -- that is, the arguments cannot be converted to the parameter types -- are removed. Of the remaining applicable candidates, either a unique best candidate is chosen. If a unique best candidate cannot be identified then overload resolution fails.&lt;/P&gt;
&lt;P mce_keep="true"&gt;Note that type inference failure is not actually an error in of itself. However, type inference failure (or success!) might cause real errors downstream in a number of ways. For example:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;if type inference fails and the candidate set becomes empty as a result, then overload resolution fails&lt;/LI&gt;
&lt;LI&gt;if type inference fails when the user intended the generic method to be the chosen one, and the remaining candidates have no unique best member, then overload resolution fails&lt;/LI&gt;
&lt;LI&gt;if type inference succeeds when it wasn't expected to then there might be more methods in the candidate set than expected. If the inferred method ties for "bestness" with another candidate then overload resolution fails. (The tiebreaker rules in overload resolution are designed to avoid this scenario, but it is still possible in contrived situations.)&lt;/LI&gt;&lt;/UL&gt;
&lt;P mce_keep="true"&gt;This then brings up the question of what error message to display when overload resolution fails. In C# 2.0 we have a heuristic which tries to detect when overload resolution failed because of the first case (which is the most common of the three cases.) In those cases it gives an error message that says "type inference failed" rather than "overload resolution failed". Even though the actual error as far as the language specification is concerned is that the candidate set contained no unique best applicable member, the user typically thinks of the cause of the error as being type inference failure in many cases, so we try to do a good job of reporting that.&lt;/P&gt;
&lt;P mce_keep="true"&gt;It works pretty well in C# 2.0, but we struggled with this a lot in C# 3.0. Suppose you end up in a situation where you have a query:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P mce_keep="true"&gt;IEnumerable&amp;lt;Customer&amp;gt; customers = ...;&lt;BR&gt;var&amp;nbsp;firstNames = from c in customers select c.FristName;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P mce_keep="true"&gt;Oops. That is going to be translated into &lt;SPAN class=code&gt;customers.Select(c=&amp;gt;c.FristName)&lt;/SPAN&gt;. There are no methods named "Select" on &lt;SPAN class=code&gt;IEnumerable&amp;lt;Customer&amp;gt;&lt;/SPAN&gt;, we look for extension methods and find &lt;SPAN class=code&gt;Enumerable.Select&amp;lt;T, R&amp;gt;(this IEnumerable&amp;lt;T&amp;gt; list, Func&amp;lt;T, R&amp;gt; selector)&lt;/SPAN&gt;. Type inference infers &lt;SPAN class=code&gt;T&lt;/SPAN&gt; as &lt;SPAN class=code&gt;Customer&lt;/SPAN&gt;, but cannot figure out what &lt;SPAN class=code&gt;R&lt;/SPAN&gt; is because &lt;SPAN class=code&gt;Customer&lt;/SPAN&gt; does not have a property &lt;SPAN class=code&gt;FristName&lt;/SPAN&gt;. Therefore type inference fails, and therefore overload resolution fails, and therefore our heuristic takes over and gives the error that type inference failed on &lt;SPAN class=code&gt;Select&lt;/SPAN&gt;.&lt;/P&gt;
&lt;P mce_keep="true"&gt;I think you would agree that the user does not think of the error in this program as being a failure of overload resolution or type inference; they think that the failure is that there's a typo in one clause of the query. Wes did quite a bit of work on the heuristics to go back one step further, and report why type inference failed; because the body of the lambda could not be successfully bound.&lt;/P&gt;
&lt;P mce_keep="true"&gt;So that's one change to type inference between C# 2.0 and C# 3.0, but I seem to have gotten ahead of myself somewhat. Next time we'll take a closer look at how the mechanism of type inference works in C# 2.0.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8611835" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Lambda+Expressions/default.aspx">Lambda Expressions</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Type+Inference/default.aspx">Type Inference</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Overload+Resolution/default.aspx">Overload Resolution</category></item><item><title>Reading Code Over the Telephone</title><link>http://blogs.msdn.com/ericlippert/archive/2008/05/16/reading-code-over-the-telephone.aspx</link><pubDate>Fri, 16 May 2008 17:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8495414</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>25</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/8495414.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=8495414</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;In my youth I once attended a lecture given by Brian Kernighan on the subject of code quality, which was very influential on my attitudes towards writing legible code. One of the things that Kernighan recommended was to endeavour write code that was so clear that it could be easily read over the phone and understood. Most people find code much easier to comprehend when read than when heard; if you can make it clear enough to be understood when heard, it's probably pretty clear code.&lt;/P&gt;
&lt;P&gt;I was reminded of this when I got the following question from&amp;nbsp;a colleague by email:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;Subject: Stupid C# 3.0 lambda expression question&lt;/P&gt;
&lt;P&gt;How does one read the =&amp;gt; operator? &lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;First off, I told my colleague that &lt;STRONG&gt;there are no stupid &lt;EM&gt;questions&lt;/EM&gt;, only stupid &lt;EM&gt;people&lt;/EM&gt;&lt;/STRONG&gt;. No stupid people work here, so don't stress about it. This is a perfectly sensible question.&lt;/P&gt;
&lt;P&gt;As far as I know, we do not have an "official" line on how to read this operator over the phone. In the absense of any other context, I personally would say &lt;SPAN class=code&gt;c=&amp;gt;c+1&lt;/SPAN&gt; as "see &lt;STRONG&gt;goes to&lt;/STRONG&gt; see plus one". Some variations that I've heard:&lt;/P&gt;
&lt;P&gt;For a projection, &lt;SPAN class=code&gt;(Customer c)=&amp;gt;c.Name&lt;/SPAN&gt;: "customer see &lt;STRONG&gt;becomes&lt;/STRONG&gt; see dot name"&lt;/P&gt;
&lt;P&gt;For a predicate, &lt;SPAN class=code&gt;(Customer c)=&amp;gt;c.Age &amp;gt; 21&lt;/SPAN&gt;: "customer see &lt;STRONG&gt;such that&lt;/STRONG&gt; see dot age is greater than twenty-one"&lt;/P&gt;
&lt;P&gt;An unfortunate conflation is that the =&amp;gt; operator looks a lot like ⇒, the "implies" operator in mathematics. Since =&amp;gt; does not have the same semantics as ⇒, it is probably a bad idea to read =&amp;gt; as "implies". (x⇒y&amp;nbsp;would have&amp;nbsp;the semantics of &lt;SPAN class=code&gt;!x|y&lt;/SPAN&gt; in C#.)&lt;/P&gt;
&lt;P&gt;Incidentally, it is a little known fact that VB6 and VBScript implemented the ⇒ operator with the &lt;SPAN class=code&gt;Imp&lt;/SPAN&gt; keyword and the ⇔ operator with the &lt;SPAN class=code&gt;Eqv&lt;/SPAN&gt; keyword. They disappeared in VB.NET. Where did they go? It is a mystery!&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8495414" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/VBScript/default.aspx">VBScript</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Lambda+Expressions/default.aspx">Lambda Expressions</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Code+Quality/default.aspx">Code Quality</category></item><item><title>Translating intentions and mechanisms</title><link>http://blogs.msdn.com/ericlippert/archive/2008/03/25/translating-intentions-and-mechanisms.aspx</link><pubDate>Tue, 25 Mar 2008 20:26:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8336141</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>12</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/8336141.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=8336141</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;Before I get into today's blogging, a quick note about my recent post on &lt;A href="http://blogs.msdn.com/ericlippert/archive/2008/02/20/how-to-not-get-a-question-answered.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2008/02/20/how-to-not-get-a-question-answered.aspx"&gt;How To Not Get A Question Answered&lt;/A&gt;. That was certainly not &lt;EM&gt;intended&lt;/EM&gt; to be fishing for compliments or chiding people for never acknowledging help ten years ago; that said, I appreciate both. Thanks to everyone who made thoughtful comments.&lt;/P&gt;
&lt;P&gt;Moving on; a theme that seems to be coming up over and over again in my recent technical conversations is that of &lt;EM&gt;intention&lt;/EM&gt; vs. &lt;EM&gt;mechanism&lt;/EM&gt;. We have tried hard in C# 3.0 to make a language where there is a good balance between the code reading as a &lt;EM&gt;declaration&lt;/EM&gt; of what &lt;EM&gt;meaning&lt;/EM&gt; you intend the code to represent, and reading as a list of &lt;EM&gt;imperative instructions&lt;/EM&gt; specifying a &lt;EM&gt;mechanism&lt;/EM&gt; which achieves those intentions. I've been accumulating anecdotes about this tension between representing intentions vs. mechanisms; expect this to be a recurring theme in the blog for the next while.&lt;/P&gt;
&lt;P&gt;Here's a question I got recently which speaks to this tension with regards to the subject of porting code from one language to another:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT color=#000080&gt;I have some C++ code with a macro in it. A typical usage looks like this:&lt;/FONT&gt; 
&lt;P&gt;&lt;FONT color=#000080&gt;TRY_WAIT_OP(Execute());&lt;/FONT&gt; 
&lt;P&gt;&lt;FONT color=#000080&gt;This macro expands to code similar to this:&lt;/FONT&gt; 
&lt;P&gt;&lt;FONT color=#000080&gt;for(int i=0; i&amp;lt;10; i++) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (Execute()) break;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Sleep(i*1000);&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#000080&gt;We are translating this code into C#, but C# does not have a #define directive. &lt;STRONG&gt;How do I do textual replacement of code in C#?&lt;/STRONG&gt; &lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Once more, we have someone &lt;A href="http://blogs.msdn.com/ericlippert/archive/2003/11/03/53333.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2003/11/03/53333.aspx"&gt;looking for a thin metal ruler&lt;/A&gt;. There's a problem -- represent the meaning of a common operation in a programming language. C++ provides a solution mechanism -- using preprocessor-based metaprogramming to create a nonstandard control flow primitive. The natural tendency when doing a translation is to find the identical mechanism in the new language, and then translate the code to use that mechanism. But what if there is no such mechanism?&lt;/P&gt;
&lt;P&gt;In that case, you've got to translate the &lt;EM&gt;intentions&lt;/EM&gt;, which after all, is what you are trying to translate in the first place. Presumably the new code is intended to do the same thing as the old code. Translating the mechanisms is just a particularly easy road to translating the intentions. What is the &lt;EM&gt;meaning&lt;/EM&gt; of this macro?&lt;/P&gt;
&lt;P&gt;Clearly TRY_WAIT_OP means "execute some arbitrary code that returns a Boolean. If it returns true, you're done. If it returns false, wait some amount of time and try again, up to ten times".&lt;/P&gt;
&lt;P&gt;Now &lt;STRONG&gt;think about how you would write code &lt;EM&gt;from scratch&lt;/EM&gt; that implemented those intentions in C#. &lt;/STRONG&gt;Don't think at all about how it was written in C++. Your goal here is to solve the same problem using a different tool, so don't use the same techniques that you used for the other tool if they're not appropriate. Use the techniques that are appropriate for &lt;EM&gt;this&lt;/EM&gt; tool. 
&lt;P&gt;The way I would write that in C# is to write a &lt;EM&gt;method&lt;/EM&gt; that takes as its argument &lt;EM&gt;some arbitrary code that returns a Boolean&lt;/EM&gt;. "Arbitrary code" is represented in C# by a &lt;EM&gt;delegate&lt;/EM&gt;. We can do a bit better than the macro while we're at it, and return a success code:&lt;SPAN class=code&gt; 
&lt;P&gt;private static bool AttemptMultiple(Func&amp;lt;bool&amp;gt; action) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Debug.Assert(action != null);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; const int maxAttempts = 10; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; const int delay = 1000; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int attempt = 0 ; attempt &amp;lt; maxAttempts ; ++attempt) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (action()) return true;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Sleep(attempt * delay); &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return false;&lt;BR&gt;} &lt;/SPAN&gt;
&lt;P&gt;Lambda expression syntax gives us a nice way to do the call: &lt;SPAN class=code&gt;
&lt;P&gt;AttemptMultiple(()=&amp;gt;Execute()); &lt;/SPAN&gt;
&lt;P&gt;A code porting project is a good opportunity to review the design fundamentals:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Why 10 retrys?&amp;nbsp; Should this be a parameter to AttemptMultiple? 
&lt;LI&gt;Why wait 1000 milliseconds instead of some other delay? Should this also be a parameter? 
&lt;LI&gt;Why is the increasing delay linear rather than constant, geometric, etc? Should the delay strategy be a parameter? &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;The above questions are good but they rather miss the point. The important question is: &lt;STRONG&gt;is this functionality even a good idea in the first place?&lt;/STRONG&gt; 
&lt;P&gt;This last point is key. The "try it, fail, wait, try again" strategy is in general a dangerous one because &lt;STRONG&gt;it does not compose well with itself&lt;/STRONG&gt;. Consider the following: &lt;SPAN class=code&gt;
&lt;P&gt;bool SendPackets()&amp;nbsp;&amp;nbsp; { ... if (!AttemptMultiple(()=&amp;gt;{ ... })) return false; ... }&lt;BR&gt;bool TalkToSocket()&amp;nbsp; { ... if (!AttemptMultiple(()=&amp;gt;SendPackets())) return false; ... }&lt;BR&gt;bool SendData()&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { ... if (!AttemptMultiple(()=&amp;gt;TalkToSocket())) return false;... }&lt;BR&gt;void HandleCommand() { ... if (command == SendData &amp;amp;&amp;amp; !AttemptMultiple(()=&amp;gt;SendData())) ReportErrorToUser();... } &lt;/SPAN&gt;
&lt;P&gt;Now suppose that the user has a bad network card and SendPackets is always going to fail. If you look at any &lt;EM&gt;one&lt;/EM&gt; of those lines, it looks like the attempt is being made ten times and will take a maximum of about one minute. In fact, the attempt to send the packet is made &lt;STRONG&gt;ten thousand&lt;/STRONG&gt; times and will not report the error to the user for about a week. 
&lt;P&gt;Usually the right thing to do when something fails is to go into a failure state &lt;EM&gt;immediately&lt;/EM&gt;. &lt;STRONG&gt;Tell the user that something failed and let them decide when and if to retry it.&lt;/STRONG&gt; 
&lt;P&gt;What are some examples of a poor mismatch between intentions and mechanisms that you guys have seen? I'm interested in stories about: 
&lt;UL&gt;
&lt;LI&gt;mechanisms that subtly did not implement the intentions of the programmer&lt;/LI&gt;
&lt;LI&gt;situations where the intention of the code was completely obscured by the mechanisms. How did you make the code better reflect the intentions?&lt;/LI&gt;
&lt;LI&gt;situations where the mechanism of the code was important, but obscured by unnecessary emphasis on representing the intention. What were the negative consequences of obscuring the mechanism behind some abstraction?&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Thanks! 
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8336141" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Lambda+Expressions/default.aspx">Lambda Expressions</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Code+Quality/default.aspx">Code Quality</category></item><item><title>Future Breaking Changes, Part Two</title><link>http://blogs.msdn.com/ericlippert/archive/2007/08/31/future-breaking-changes-part-two.aspx</link><pubDate>Fri, 31 Aug 2007 17:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4649198</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>9</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/4649198.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=4649198</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;&lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2007/08/30/future-breaking-changes-part-one.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2007/08/30/future-breaking-changes-part-one.aspx"&gt;Last time&lt;/A&gt; I mentioned that one of the subtleties of programming language design is weighing the benefit of adding a feature against the pain it will cause you in the future. This is a specific&amp;nbsp;subset of a more general set of problems. Languages run into the same problem that other large, multiply-versioned software products run into; if you have n existing features and want to add m new features, then you have at least m x n possible interactions to consider. In an ideal world the features would all be &lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2005/10/28/483905.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2005/10/28/483905.aspx"&gt;orthogonal&lt;/A&gt; to each other, but in reality of course new features modify the behaviour of existing features. &lt;/P&gt;
&lt;P&gt;Just as a random example, what on earth do &lt;A class="" href="http://blogs.msdn.com/wesdyer/archive/2007/05/23/in-case-you-haven-t-heard.aspx" mce_href="http://blogs.msdn.com/wesdyer/archive/2007/05/23/in-case-you-haven-t-heard.aspx"&gt;partial methods&lt;/A&gt; have to do with &lt;A class="" href="http://www.interact-sw.co.uk/iangblog/2005/09/30/expressiontrees" mce_href="http://www.interact-sw.co.uk/iangblog/2005/09/30/expressiontrees"&gt;expression trees&lt;/A&gt;? Both are new features for C# 3.0, but other than that, they seem to have nothing to do with each other. But what happens when you have an expression tree lambda which contains &lt;EM&gt;a call to a partial method which is going to be removed&lt;/EM&gt;? This interaction has to be carefully defined. &lt;EM&gt;Every interaction between every feature has to be carefully defined&lt;/EM&gt;, and the larger the area of the feature interaction is, the more likely it is that there will be unfortunate consequences of this nonorthogonality, such as breaking changes.&lt;/P&gt;
&lt;P&gt;I said last time that implicitly typed&amp;nbsp;lambdas are just such a feature -- big surface area of nonorthogonal interactions which will lead to future breaking changes. I'd like to explore that in more detail, because it might not be immediately obvious why that is the case.&lt;/P&gt;
&lt;P&gt;The rule for determining whether an &lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2007/01/10/lambda-expressions-vs-anonymous-methods-part-one.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2007/01/10/lambda-expressions-vs-anonymous-methods-part-one.aspx"&gt;implicitly typed lambda&lt;/A&gt; is convertible to a given delegate type is (somewhat simplified) “If possible, infer the return type and the types of the lambda parameters from the delegate type. Try to&amp;nbsp;bind the lambda with those types. If the inference and&amp;nbsp;binding succeeds&amp;nbsp;with no errors&amp;nbsp;then the lambda expression is convertible to that delegate type.” &lt;/P&gt;
&lt;P&gt;For example, if we had a lambda expression like &lt;SPAN class=code&gt;x=&amp;gt;x - 123.4&lt;/SPAN&gt;, that would be convertible to &lt;SPAN class=code&gt;&lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2006/06/21/641831.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2006/06/21/641831.aspx"&gt;Func&amp;lt;double, double&amp;gt;&lt;/A&gt;&lt;/SPAN&gt; but not to &lt;SPAN class=code&gt;Func&amp;lt;string, double&amp;gt;&lt;/SPAN&gt; (because the subtraction cannot be legally bound) or &lt;SPAN class=code&gt;Func&amp;lt;double, int&amp;gt;&lt;/SPAN&gt; (because&amp;nbsp;the conversion to the return type cannot be bound).&lt;/P&gt;
&lt;P&gt;Notice how the overlap between this new feature – implicitly typed lambda convertibility to a delegate type – overlaps with&amp;nbsp;almost every other feature&amp;nbsp;in the entire C# language. Consider the impact of this design decision on the potential for breaking changes in the future. &lt;EM&gt;Every single time we make a change to the rules for how the body of a method is bound, we are potentially changing whether a given lambda expression is convertible to a given type.&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;Now, is that really so bad? Generally when we make changes to the method body binding rules, we do so in as non-breaking a manner as possible. We should never be making an existing lambda that &lt;EM&gt;does&lt;/EM&gt; convert suddenly &lt;EM&gt;stop&lt;/EM&gt; converting, because then we would also be breaking compilation of the equivalent &lt;EM&gt;nominal&lt;/EM&gt; method body. Really we should only be causing presently-erroneous code to suddenly start being non-erroneous, and as we’ve already discussed, that’s not a breaking change.&lt;/P&gt;
&lt;P&gt;Or is it?&lt;/P&gt;
&lt;P&gt;Actually, now in a lot of cases it could be.&lt;/P&gt;
&lt;P&gt;Consider a silly example. Suppose we decide that in some hypothetical C# 4.0(‡) language it should be legal to subtract a double from a string. That’s not entirely farfetched – that’s perfectly legal in JScript. You just convert the&amp;nbsp;string to a number&amp;nbsp;and subtract. We might reason that this new feature is not a breaking change, because no program that ever&amp;nbsp;subtracted a double from a string&amp;nbsp;ever compiled before. But it &lt;EM&gt;is&lt;/EM&gt; a breaking change, because now &lt;EM&gt;this&lt;/EM&gt; program stops compiling:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;using System;&lt;BR&gt;class Program {&lt;BR&gt;&amp;nbsp; void M(Func&amp;lt;double, int&amp;gt; f){}&lt;BR&gt;&amp;nbsp; void M(Func&amp;lt;string, double&amp;gt; f){}&lt;BR&gt;&amp;nbsp; void M(Func&amp;lt;double, double&amp;gt; f){}&lt;BR&gt;&amp;nbsp; static void Main() {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; M(x=&amp;gt;x-123.4);&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Before the change, the program unambiguously chooses the third overload. But with our change to addition semantics, now the second and third overloads would both work. Neither would be clearly better than the other. The compiler would then give an ambiguity error. Thus, this is a breaking change. &lt;/P&gt;
&lt;P&gt;It gets even worse; with some cleverness we could come up with more subtle breaking changes, where the compiler would not produce an error but instead would choose a &lt;EM&gt;different&lt;/EM&gt; overload than before. At least a program which fails to compile calls attention to the problem; recompiling and having the behaviour change subtly might go unnoticed for a long time.&lt;/P&gt;
&lt;P&gt;This is a general problem with overload resolution: it depends upon conversion semantics. If we make the conversion semantics more strict then it is possible to go from having exactly one overload which works to zero, which is a breaking change. If we make the conversion semantics less strict then it is possible to go from having exactly one overload which works to two, which is also (usually) a breaking change.&lt;/P&gt;
&lt;P&gt;Since lambda convertibility depends on every other language rule for binding an expression, any change to &lt;EM&gt;any&lt;/EM&gt; of those rules is a potential change in convertibility, and hence a potential breaking change for overload resolution. Now, hopefully few real-world codebases will end up in the above situation, where a method is overloaded solely on a bunch of different delegate types, but still, I worry. We think implicitly typed lambdas are worth it, but this was a tough call that we agonized over for a long time.&lt;/P&gt;
&lt;P&gt;Next time on FAIC: More on subtle language design issues involving breaking changes. Have a pleasant Labour Day weekend, Canadian and American readers!&lt;/P&gt;
&lt;HR&gt;

&lt;P&gt;(‡) I call out that this is the &lt;EM&gt;hypothetical&lt;/EM&gt; C# 4.0 compiler because of course I do not discuss the feature set of unannounced and non-existing products on public blogs. &lt;BR&gt;&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=4649198" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Breaking+Changes/default.aspx">Breaking Changes</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Lambda+Expressions/default.aspx">Lambda Expressions</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Overload+Resolution/default.aspx">Overload Resolution</category></item><item><title>FYI: C# and VB Closures are per-scope</title><link>http://blogs.msdn.com/ericlippert/archive/2007/06/06/fyi-c-and-vb-closures-are-per-scope.aspx</link><pubDate>Thu, 07 Jun 2007 01:18:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:3145989</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>8</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/3145989.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=3145989</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;This post assumes that you understand &lt;A class="" href="http://blogs.msdn.com/oldnewthing/archive/2006/08/02/686456.aspx" mce_href="http://blogs.msdn.com/oldnewthing/archive/2006/08/02/686456.aspx"&gt;how closures are implemented in C#.&lt;/A&gt; They're implemented in &lt;A class="" href="http://blogs.msdn.com/vbteam/archive/2007/05/25/closures-in-vb-part-3-scope.aspx" mce_href="http://blogs.msdn.com/vbteam/archive/2007/05/25/closures-in-vb-part-3-scope.aspx"&gt;essentially the same way in the&amp;nbsp;upcoming version of Visual Basic.&lt;/A&gt;&amp;nbsp; As &lt;A class="" href="http://blogs.msdn.com/oldnewthing/default.aspx" mce_href="http://blogs.msdn.com/oldnewthing/default.aspx"&gt;Raymond&lt;/A&gt; and &lt;A class="" href="http://blogs.msdn.com/grantri/default.aspx" mce_href="http://blogs.msdn.com/grantri/default.aspx"&gt;Grant&lt;/A&gt; point out in their various articles on the subject, the question of&amp;nbsp;whether or not two instances of a delegate share a closed-over variable or have their own copy &lt;A class="" href="http://blogs.msdn.com/oldnewthing/archive/2006/08/04/688527.aspx" mce_href="http://blogs.msdn.com/oldnewthing/archive/2006/08/04/688527.aspx"&gt;depends on where the variable is in scope in relation to the delegate creation&lt;/A&gt;.&amp;nbsp;I think that this issue is reasonably well-documented by these guys. &lt;A class="" href="http://blogs.msdn.com/grantri/archive/category/3378.aspx" mce_href="http://blogs.msdn.com/grantri/archive/category/3378.aspx"&gt;Lots has been written on this subject already&lt;/A&gt;; no need for me to recap it all&amp;nbsp;here.&lt;/P&gt;
&lt;P&gt;However, a related issue which I haven't seen anyone talk much about is what the consequences of having one closure per scope are. Though it makes the closure semantics conceptually easier to think about (and implement!), it can lead to an unfortunate problem with garbage collection. Consider the following:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;Func&amp;lt;Cheap&amp;gt;&amp;nbsp;M(){&lt;BR&gt;&amp;nbsp; Cheap c = new Cheap();&lt;BR&gt;&amp;nbsp; Expensive e = new Expensive();&lt;BR&gt;&amp;nbsp; Func&amp;lt;Expensive&amp;gt; shortlived = ()=&amp;gt;e;&lt;BR&gt;&amp;nbsp; Func&amp;lt;Cheap&amp;gt; longlived = ()=&amp;gt;c;&lt;BR&gt;&amp;nbsp; // use shortlived&lt;BR&gt;&amp;nbsp; // use longlived&lt;BR&gt;&amp;nbsp; return longlived;&lt;BR&gt;}&amp;nbsp; &lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;If the short-lived delegate does not survive past the end of the method, when is the expensive resource released?&lt;/P&gt;
&lt;P&gt;The closure for the short-lived delegate owns the expensive resource. But since there is one closure per scope, both the short-lived and the long-lived delegates own a single closure. The closure cannot be collected until every delegate that owns it is dead. Therefore the expensive resource is not released until the long-lived delegate is released, even though the long-lived delegate does not reference the expensive resource!&lt;/P&gt;
&lt;P&gt;We could solve this problem in the compilers by coming up with a smarter mechanism for determining how to create closures, and perhaps some day we will, but it will not be in C# 3.0. Until that day, if you are creating&amp;nbsp;what you think are short-lived anonymous methods or lambdas or queries which close over expensive resources, you might want to explicitly finalize those resources when you know that you're done with them. It's easy to accidentally make the resource live longer than you think it does.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=3145989" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Lambda+Expressions/default.aspx">Lambda Expressions</category></item><item><title>Lambda Expressions vs. Anonymous Methods, Part Five</title><link>http://blogs.msdn.com/ericlippert/archive/2007/03/28/lambda-expressions-vs-anonymous-methods-part-five.aspx</link><pubDate>Wed, 28 Mar 2007 17:45:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1956384</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>6</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/1956384.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=1956384</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;&lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2007/03/26/lambda-expressions-vs-anonymous-methods-part-four.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2007/03/26/lambda-expressions-vs-anonymous-methods-part-four.aspx"&gt;Last time&lt;/A&gt; I demonstrated that the compiler could have to do an exponential number of bindings in order to determine whether there was a unique best overload resolution for a function call that takes a lambda. Some of you may have wondered whether we simply were not being clever enough in the compiler. Perhaps there is some way to optimize this problem so that the unique solution is found in less than exponential time. &lt;/P&gt;
&lt;P&gt;As it turns out, the question of whether there is a clever way to do this in C# 3.0&amp;nbsp;is equivalent to solving the most famous unsolved problem in computer science. That is a problem which has stumped generations of the finest minds in academia,&amp;nbsp;and is widely believed to be unsolvable, so I don't feel &lt;EM&gt;particularly&lt;/EM&gt; bad about not solving this one myself. &lt;/P&gt;
&lt;P&gt;Consider the following &lt;EM&gt;slight&lt;/EM&gt; revision of the set of overloads I sketched out last time:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;class MainClass&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; class T{}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; class F{}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; delegate void DT(T t);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; delegate void DF(F f);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static void M(DT dt)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.Console.WriteLine("true");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dt(new T());&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static void M(DF df)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.Console.WriteLine("false");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; df(new F());&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static T Or(T a1, T a2){return new T();}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static T Or(T a1, F a2){return new T();}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static T Or(F a1, T a2){return new T();}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static F Or(F a1, F a2){return new F();}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static T And(T a1, T a2){return new T();}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static F And(T a1, F a2){return new F();}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static F And(F a1, T a2){return new F();}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static F And(F a1, F a2){return new F();}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static F Not(T a){return new F();}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static T Not(F a){return new T();}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static void MustBeT(T t){}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static void Main()&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Introduce enough variables and then&amp;nbsp;encode any Boolean predicate:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp;eg,&amp;nbsp;here we encode (!x3) &amp;amp; ((!x1) &amp;amp; ((x1 | x2) &amp;amp; (x2 | x3)))&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; M(x1=&amp;gt;M(x2=&amp;gt;M(x3=&amp;gt;MustBeT(&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; And(&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Not(x3),&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; And(&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Not(x1),&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; And(&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Or(x1, x2),&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Or(x2, x3))))))));&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;This expression&amp;nbsp;&lt;I&gt;makes the compiler solve the &lt;A class="" href="http://en.wikipedia.org/wiki/Boolean_satisfiability_problem" mce_href="http://en.wikipedia.org/wiki/Boolean_satisfiability_problem"&gt;Boolean satisfiability problem&lt;/A&gt;&lt;/I&gt; (aka "SAT"). If SAT has a unique solution then the program compiles and produces the unique solution. If it has more than one solution then compilation fails with an ambiguity error. If it has no solution then the program fails with the error that &lt;SPAN class=code&gt;MustBeT&lt;/SPAN&gt; has an &lt;SPAN class=code&gt;F&lt;/SPAN&gt; argument. But no matter how you slice it, the compiler must solve SAT. &lt;/P&gt;
&lt;P&gt;Determining whether a given predicate has a set of valuations for its variables which make it true is an &lt;A class="" href="http://en.wikipedia.org/wiki/NP-complete" mce_href="http://en.wikipedia.org/wiki/NP-complete"&gt;NP-complete&lt;/A&gt; problem; actually &lt;EM&gt;finding&lt;/EM&gt; the set of valuations is an &lt;A class="" href="http://en.wikipedia.org/wiki/NP-hard" mce_href="http://en.wikipedia.org/wiki/NP-hard"&gt;NP-hard&lt;/A&gt; problem. Therefore, &lt;EM&gt;overload resolution in C# 3.0&amp;nbsp;is at the very least NP-hard&lt;/EM&gt;. There is no known polynomial-time algorithm for any NP-complete or NP-hard problem and it is widely believed that there is none to be found, though that conjecture has yet to be proven. So our dream of fast lambda type analysis in C# 3.0&amp;nbsp;is almost certainly doomed, at least as long as we have the current rules for overload resolution. &lt;/P&gt;
&lt;P&gt;Does this really matter in practice? As I mentioned last time, hopefully not. Other languages also have this issue. When I ran an early&amp;nbsp;draft of this post&amp;nbsp;past him, &lt;A class="" href="http://research.microsoft.com/~emeijer/" mce_href="http://research.microsoft.com/~emeijer/"&gt;Erik Meijer&lt;/A&gt; immeditely pointed out that the &lt;A class="" href="http://en.wikipedia.org/wiki/ML_programming_language" mce_href="http://en.wikipedia.org/wiki/ML_programming_language"&gt;ML&lt;/A&gt; type inference system has &lt;A class="" href="http://portal.acm.org/citation.cfm?id=96748&amp;amp;coll=portal&amp;amp;dl=ACM" mce_href="http://portal.acm.org/citation.cfm?id=96748&amp;amp;coll=portal&amp;amp;dl=ACM"&gt;similar worst cases&lt;/A&gt;, and the &lt;A class="" href="http://en.wikipedia.org/wiki/Haskell_%28programming_language%29" mce_href="http://en.wikipedia.org/wiki/Haskell_%28programming_language%29"&gt;Haskell&lt;/A&gt; type inference system is even worse. Apparently in Haskell you can encode a Turing machine into the type system and make the compiler run it! In practice these sorts of problems do not arise in real-world code in any of these languages, so I am not too worried about it for C# 3.0. &lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1956384" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Performance/default.aspx">Performance</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Rarefied+Heights/default.aspx">Rarefied Heights</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Lambda+Expressions/default.aspx">Lambda Expressions</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Overload+Resolution/default.aspx">Overload Resolution</category></item><item><title>Lambda Expressions vs. Anonymous Methods, Part Four</title><link>http://blogs.msdn.com/ericlippert/archive/2007/03/26/lambda-expressions-vs-anonymous-methods-part-four.aspx</link><pubDate>Tue, 27 Mar 2007 02:05:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1955901</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>9</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/1955901.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=1955901</wfw:commentRss><description>&lt;DIV class=mine&gt;Hey all, sorry for the long time between posts; I have been crazy busy &lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2007/01/30/free-food-and-meet-the-compiler-guy-and-win-an-xbox-360.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2007/01/30/free-food-and-meet-the-compiler-guy-and-win-an-xbox-360.aspx"&gt;recruiting&lt;/A&gt;, interviewing, fixing bugs, making performance improvements and implementing last-minute changes to the language and expression tree library. The last few posts about lambda binding yielded many interesting comments which I hope to address over the next month or so. 
&lt;P&gt;Before that though -- back when I &lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2007/01/10/lambda-expressions-vs-anonymous-methods-part-one.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2007/01/10/lambda-expressions-vs-anonymous-methods-part-one.aspx"&gt;started&lt;/A&gt; this series of posts I noted that lambda expressions have an interesting property. Namely, &lt;EM&gt;the semantic analysis of the lambda body may depend upon what type the lambda is being converted to&lt;/EM&gt;. This seemingly trivial fact has an important impact upon the compiler performance during analysis. At long last, let me demonstrate the impact this fact has. &lt;/P&gt;
&lt;P&gt;Consider the following set of overloads: &lt;/P&gt;
&lt;P&gt;&lt;SPAN class=code&gt;int M(Func&amp;lt;int, int&amp;gt; f){ /* whatever ... */ }&lt;BR&gt;string M(Func&amp;lt;string, string&amp;gt; f){ /* whatever ... */ }&lt;BR&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;Now suppose we have a call with a lambda argument: &lt;/P&gt;
&lt;P&gt;&lt;SPAN class=code&gt;M(x=&amp;gt;x.ToUpper()); &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;During overload resolution we make a list of all the potential overloads and we see which are applicable. That is, which overloads have the property that all of the arguments are convertible to the types of their corresponding formal parameters. Then of all the applicable methods, we pick the best match if there happens to be more than one. &lt;/P&gt;
&lt;P&gt;Therefore we must try this binding two ways. We try it as though it were &lt;/P&gt;
&lt;P&gt;&lt;SPAN class=code&gt;M((int x)=&amp;gt;x.ToUpper()); &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;and &lt;/P&gt;
&lt;P&gt;&lt;SPAN class=code&gt;M((string x)=&amp;gt;x.ToUpper()); &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;The former produces an error while binding the body because there is no &lt;SPAN class=code&gt;ToUpper&lt;/SPAN&gt; method on &lt;SPAN class=code&gt;int&lt;/SPAN&gt;. The latter binds the body correctly and the return type matches the expected return type, so this one succeeds. The first &lt;SPAN class=code&gt;M&lt;/SPAN&gt; is not applicable so it is discarded, the second one is applicable, so it is chosen, all is good in the world. &lt;/P&gt;
&lt;P&gt;Or is it? &lt;/P&gt;
&lt;P&gt;What if we did something crazy like this? &lt;/P&gt;
&lt;P&gt;&lt;SPAN class=code&gt;M(x1=&amp;gt;M(x2=&amp;gt;x1.ToLower() + x2.ToUpper()); &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;OK, so now what do we do? We try to do overload resolution on the outer call. Again, we must try both &lt;SPAN class=code&gt;int&lt;/SPAN&gt; and &lt;SPAN class=code&gt;string&lt;/SPAN&gt; as candidates for &lt;SPAN class=code&gt;x1&lt;/SPAN&gt;. But then when we get to the outer body, we are faced with the same problem for &lt;SPAN class=code&gt;x2&lt;/SPAN&gt;. &lt;/P&gt;
&lt;P&gt;We have to try all four possibilities for &lt;SPAN class=code&gt;{x1, x2}&lt;/SPAN&gt; (that is, &lt;SPAN class=code&gt;{int, int}&lt;/SPAN&gt;, &lt;SPAN class=code&gt;{int, string}&lt;/SPAN&gt;, &lt;SPAN class=code&gt;{string, int}&lt;/SPAN&gt; and &lt;SPAN class=code&gt;{string, string}&lt;/SPAN&gt;) in order to determine how many of them work, and of the ones that work, which one is the best. In this particular example "both are string" is the only one that works. (We could with a little more cleverness come up with examples where there were multiple possible matches that worked.) &lt;/P&gt;
&lt;P&gt;So perhaps you see where this is going. If there are m overloads that are nested in this manner n deep, then the compiler must try m&lt;SUP&gt;n&lt;/SUP&gt; possibilities in order to determine which is the unique best one. If it's 2&lt;SUP&gt;2&lt;/SUP&gt; = 4, that's not a big deal. If we triple each and go to 6&lt;SUP&gt;6&lt;/SUP&gt; = 46656, that's rather a lot of binding to do, and it takes up rather a lot of time and memory. &lt;/P&gt;
&lt;P&gt;Does this seem like a contrived example? Unfortunately, it is not. In the original prototype of C# 3.0, nested &lt;SPAN class=code&gt;from&lt;/SPAN&gt; clauses in queries were translated into nested lambdas in &lt;EM&gt;exactly&lt;/EM&gt; this manner, and most of the translation methods have at least two overloads, some have many more. We were easily getting into situations where simple queries could involve &lt;I&gt;millions&lt;/I&gt; of body bindings. Fortunately we realized the problem in time; my colleague &lt;A class="" href="http://blogs.msdn.com/wesdyer/" mce_href="http://blogs.msdn.com/wesdyer/"&gt;Wes&lt;/A&gt; came up with an alternative translation strategy which does not generate nested lambdas so aggressively and we therefore avoid this problem in the common case. You can still get into it yourself though; please do not.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Next time I'll create a truly contrived (and rather hilarious) example which demonstrates just how bad things can get and just how hard you can make the compiler work to do overload resolution on lambdas.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1955901" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Performance/default.aspx">Performance</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Lambda+Expressions/default.aspx">Lambda Expressions</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Overload+Resolution/default.aspx">Overload Resolution</category></item><item><title>Lambda Expressions vs. Anonymous Methods, Part Three</title><link>http://blogs.msdn.com/ericlippert/archive/2007/01/12/lambda-expressions-vs-anonymous-methods-part-three.aspx</link><pubDate>Fri, 12 Jan 2007 20:45:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1456819</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>15</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/1456819.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=1456819</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;&lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2007/01/11/lambda-expressions-vs-anonymous-methods-part-two.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2007/01/11/lambda-expressions-vs-anonymous-methods-part-two.aspx"&gt;Last time&lt;/A&gt; I said that I would describe a sneaky trick whereby you can get variable type inference out of a lambda by using method type inference. &lt;/P&gt;
&lt;P&gt;First off, I want to again emphasize that the reason we are adding so many type inferencing features to C# 3.0 is not just because it is convenient to reduce the redundancy currently required. That's a nice-to-have feature, but certainly not a must-have feature. No, the reason why we are adding so many type inferencing features is because we are adding &lt;EM&gt;anonymous types&lt;/EM&gt;.&amp;nbsp;(We are adding anonymous types because they make writing queries so much more pleasant.)&amp;nbsp;Since an anonymous type is, by definition, nameless, you need to be able to infer the type of anything which would otherwise have to be declared with a type name.&lt;/P&gt;
&lt;P&gt;But if the type of a lambda expression comes from its target type, and the target type has to be named in the declaration, how can you create a lambda expression which, say, returns an anonymous type?&lt;/P&gt;
&lt;P&gt;&lt;SPAN class=code&gt;var f = (Customer c)=&amp;gt;new {c.Name, c.Age, c.Address};&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;We have no way of saying in any type declaration what the type of the return is.&amp;nbsp; The best we can do is the incredibly weak&lt;/P&gt;
&lt;P&gt;&lt;SPAN class=code&gt;Func&amp;lt;Customer, object&amp;gt;&amp;nbsp;f = (Customer c)=&amp;gt;new {c.Name, c.Age, c.Address};&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;Yuck, all the type information about the tuple has been lost. We can do better than this.&lt;/P&gt;
&lt;P&gt;The trick here is that we have extended the type inferencing algorithm on methods so that&lt;STRONG&gt; generic method type variables can be inferred from the return types of lambdas&lt;/STRONG&gt;. Suppose we have this little helper identity function:&lt;/P&gt;
&lt;P&gt;&lt;SPAN class=code&gt;Func&amp;lt;A, R&amp;gt; MakeFunction&amp;lt;A, R&amp;gt;(Func&amp;lt;A, R&amp;gt; f) { return f; }&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;Now look what happens when we say&lt;/P&gt;
&lt;P&gt;&lt;SPAN class=code&gt;var f = MakeFunction((Customer c)=&amp;gt;new {c.Name, c.Age, c.Address});&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;The method type inferencing engine says ok, we have an actual argument which is a lambda from &lt;SPAN class=code&gt;Customer&lt;/SPAN&gt; to some anonymous tuple type. We have a formal parameter which is a delegate from &lt;SPAN class=code&gt;A&lt;/SPAN&gt; to &lt;SPAN class=code&gt;R&lt;/SPAN&gt;. Therefore &lt;SPAN class=code&gt;A&lt;/SPAN&gt; is &lt;SPAN class=code&gt;Customer&lt;/SPAN&gt;, &lt;SPAN class=code&gt;R&lt;/SPAN&gt; is the anonymous tuple type. Now we know the return type of this generic function, and therefore abracadabra, the right hand side of the declaration has a type, so it is legal! (And it's not even particularly unperformant, since the jitter will likely optimize away the identity function. Even if it doesn't, it's tiny compared to the cost of creating the delegate object.)&lt;/P&gt;
&lt;P&gt;What if the lambda has an anonymous type for its parameter? Suppose we want a function from the anonymous tuple type above which returns a string. This is a little kludgier but we can still do it:&lt;/P&gt;
&lt;P&gt;&lt;SPAN class=code&gt;Func&amp;lt;A, R&amp;gt; MakeFunction&amp;lt;A, R&amp;gt;(Func&amp;lt;A, R&amp;gt; f, A a) { return f; }&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN class=code&gt;var f = MakeFunction(c=&amp;gt;c.Name,&amp;nbsp;new {Name="", Age=0, Address=""} );&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;Now the type inference engine can't infer anything from the lambda parameter, since it is untyped. But it can infer the parameter type from the second actual argument. Once it knows the type of &lt;SPAN class=code&gt;A&lt;/SPAN&gt;, it can infer &lt;SPAN class=code&gt;R&lt;/SPAN&gt; from the return type of the lambda.&lt;/P&gt;
&lt;P&gt;Pretty neat, eh? &lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1456819" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Lambda+Expressions/default.aspx">Lambda Expressions</category></item><item><title>Lambda Expressions vs. Anonymous Methods, Part Two</title><link>http://blogs.msdn.com/ericlippert/archive/2007/01/11/lambda-expressions-vs-anonymous-methods-part-two.aspx</link><pubDate>Thu, 11 Jan 2007 23:40:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1451894</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>6</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/1451894.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=1451894</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;We interrupt the discussion of how the difference between lambda expression and anonymous method convertibility leads to potential performance problems in the compiler to answer a user question. &lt;/P&gt;
&lt;P&gt;Within hours of yesterday's post readers &lt;A href="http://blogs.msdn.com/oldnewthing" mce_href="http://blogs.msdn.com/oldnewthing"&gt;Raymond Chen&lt;/A&gt; and &lt;A href="http://musingmarc.blogspot.com/" mce_href="http://musingmarc.blogspot.com/"&gt;Marc Brooks&lt;/A&gt; both asked me the same question. &lt;B&gt;How do lambdas and anonymous methods interact with implicitly typed local variables?&lt;/B&gt; &lt;/P&gt;
&lt;P&gt;Recall that C# 3.0 will support implicitly typed local variables. This: &lt;/P&gt;
&lt;P&gt;&lt;SPAN class=code&gt;var d = new Dictionary&amp;lt;string, List&amp;lt;int&amp;gt;&amp;gt;(); &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;is a syntactic sugar for &lt;/P&gt;
&lt;P&gt;&lt;SPAN class=code&gt;Dictionary&amp;lt;string, List&amp;lt;int&amp;gt;&amp;gt; d = new Dictionary&amp;lt;string, List&amp;lt;int&amp;gt;&amp;gt;(); &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;Again, I wish to emphasize that &lt;A href="http://blogs.msdn.com/ericlippert/archive/2005/09/27/474462.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2005/09/27/474462.aspx"&gt;C# 3.0 is still statically typed, honest!&lt;/A&gt; The &lt;SPAN class=code&gt;var&lt;/SPAN&gt; keyword does not have the semantics of the JScript &lt;SPAN class=code&gt;var&lt;/SPAN&gt; or VBScript's &lt;SPAN class=code&gt;Variant&lt;/SPAN&gt; or any such thing. It simply means "the variable is the type of the right side of the declaration". We are committed to keeping C# 3.0 a &lt;A href="http://blogs.msdn.com/wesdyer/archive/2006/12/20/types-of-confusion.aspx" mce_href="http://blogs.msdn.com/wesdyer/archive/2006/12/20/types-of-confusion.aspx"&gt;statically typed&lt;/A&gt; language. &lt;/P&gt;
&lt;P&gt;You will note that a key requirement there is that the right hand side actually has a type. Furthermore, it cannot be the null type or the void type, obviously. So then what should this do? &lt;/P&gt;
&lt;P&gt;&lt;SPAN class=code&gt;var f = i=&amp;gt;F(i); &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;Clearly this cannot be legal; since as I discussed &lt;A href="http://blogs.msdn.com/ericlippert/archive/2007/01/10/lambda-expressions-vs-anonymous-methods-part-one.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2007/01/10/lambda-expressions-vs-anonymous-methods-part-one.aspx"&gt;yesterday&lt;/A&gt; the type of the formal parameter is determined from the target type, and we are trying to determine the target type, we have a chicken-and-egg problem where there is not enough information to determine the type. &lt;/P&gt;
&lt;P&gt;What about this? &lt;/P&gt;
&lt;P&gt;&lt;SPAN class=code&gt;var f = (int i)=&amp;gt;i; &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;Here we know the type of the parameter, we can infer the type of the return easily enough, it's the same type as the parameter! We're set, right? &lt;/P&gt;
&lt;P&gt;Not so fast. &lt;/P&gt;
&lt;P&gt;Consider the following type declarations: &lt;/P&gt;
&lt;P&gt;&lt;SPAN class=code&gt;public delegate int D1(int i);&lt;BR&gt;public delegate int D2(int i);&lt;BR&gt;public delegate int D3&amp;lt;A&amp;gt;(A a);&lt;BR&gt;public delegate R D4&amp;lt;A, R&amp;gt;(A a);&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;If the &lt;SPAN class=code&gt;var&lt;/SPAN&gt; were replaced by &lt;SPAN class=code&gt;D1&lt;/SPAN&gt;, &lt;SPAN class=code&gt;D2&lt;/SPAN&gt;, &lt;SPAN class=code&gt;D3&amp;lt;int&amp;gt;&lt;/SPAN&gt;, &lt;SPAN class=code&gt;D4&amp;lt;int, int&amp;gt;&lt;/SPAN&gt;, or for that matter, &lt;SPAN class=code&gt;D4&amp;lt;int, double&amp;gt;&lt;/SPAN&gt; or &lt;SPAN class=code&gt;D4&amp;lt;int, object&amp;gt;&lt;/SPAN&gt;, we'd have a legal program. So what &lt;EM&gt;is&lt;/EM&gt; the type of the right hand side? How can we choose which of these is the best?&lt;/P&gt;
&lt;P&gt;We can't. Delegate types are not even structurally equivalent; you can't even assign a variable of type &lt;SPAN class=code&gt;D1&lt;/SPAN&gt; to a variable of type &lt;SPAN class=code&gt;D2&lt;/SPAN&gt;. We would always potentially choose wrong.&lt;/P&gt;
&lt;P&gt;What this tells us is that it is more than just that the formal parameter types of an implicitly typed lambda expression flow from the target type. The type of the &lt;EM&gt;entire&lt;/EM&gt; lambda expression flows from the target type, and therefore, &lt;STRONG&gt;lambda expressions themselves must have no type&lt;/STRONG&gt;. &lt;/P&gt;
&lt;P&gt;And in fact the C# 2.0 specification calls this out. Method group expressions and anonymous method expressions are &lt;EM&gt;typeless expressions&lt;/EM&gt; in C# 2.0, and lambda expressions join them in C# 3.0. Therefore it is illegal for them to appear "naked" on the right hand side of an implicit declaration.&lt;/P&gt;
&lt;P&gt;This is rather unfortunate because it makes it difficult to declare a variable of type "delegate which takes or returns an anonymous type". The whole point of the var feature in the first place is to make anonymous types work, and yet we seem to have a hole here. As it turns out, it is possible! Next time I'll describe a clever trick whereby we can use &lt;EM&gt;method type inference&lt;/EM&gt; to make variable type inference work correctly on lambdas which take anonymous types.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1451894" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Lambda+Expressions/default.aspx">Lambda Expressions</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Type+Inference/default.aspx">Type Inference</category></item></channel></rss>