<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US"><title type="html">Fabulous Adventures In Coding</title><subtitle type="html">Eric Lippert's Blog</subtitle><id>http://blogs.msdn.com/ericlippert/atom.xml</id><link rel="alternate" type="text/html" href="http://blogs.msdn.com/ericlippert/default.aspx" /><link rel="self" type="application/atom+xml" href="http://blogs.msdn.com/ericlippert/atom.xml" /><generator uri="http://communityserver.org" version="2.1.61025.2">Community Server</generator><updated>2009-09-24T06:53:00Z</updated><entry><title>Closing over the loop variable considered harmful</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/ericlippert/archive/2009/11/12/closing-over-the-loop-variable-considered-harmful.aspx" /><id>http://blogs.msdn.com/ericlippert/archive/2009/11/12/closing-over-the-loop-variable-considered-harmful.aspx</id><published>2009-11-12T14:50:00Z</published><updated>2009-11-12T14:50:00Z</updated><content type="html">&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;</content><author><name>EricLippert</name><uri>http://blogs.msdn.com/members/EricLippert.aspx</uri></author><category term="C#" scheme="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx" /><category term="Breaking Changes" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Breaking+Changes/default.aspx" /><category term="Lambda Expressions" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Lambda+Expressions/default.aspx" /><category term="Language Design" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Language+Design/default.aspx" /><category term="foreach" scheme="http://blogs.msdn.com/ericlippert/archive/tags/foreach/default.aspx" /><category term="closures" scheme="http://blogs.msdn.com/ericlippert/archive/tags/closures/default.aspx" /></entry><entry><title>Three Umpires</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/ericlippert/archive/2009/11/09/three-umpires.aspx" /><id>http://blogs.msdn.com/ericlippert/archive/2009/11/09/three-umpires.aspx</id><published>2009-11-09T15:01:00Z</published><updated>2009-11-09T15:01:00Z</updated><content type="html">&lt;DIV class=mine&gt;
&lt;P&gt;Three baseball umpires are having lunch together. The first umpire says "Well, a lot of them are balls, and a lot of them are strikes, but I always calls 'em as I sees 'em."&lt;/P&gt;
&lt;P&gt;The second umpire says "Hmph. I calls 'em as they &lt;EM&gt;are&lt;/EM&gt;."&lt;/P&gt;
&lt;P&gt;The third umpire slowly looks at his two colleagues and declares "They ain't &lt;EM&gt;nothin' &lt;/EM&gt;until I calls 'em."&lt;/P&gt;
&lt;HR&gt;

&lt;P&gt;Those of you unfamiliar with the bizarre rules of baseball might need a brief primer. Suppose the pitcher throws a pitch and the batter swings and misses. &lt;A class="" href="http://www.amazon.com/gp/recsradio/radio/B000002MSU/ref=pd_krex_dp_001_006/176-2812138-0508753?ie=UTF8&amp;amp;track=006&amp;amp;disc=001" mce_href="http://www.amazon.com/gp/recsradio/radio/B000002MSU/ref=pd_krex_dp_001_006/176-2812138-0508753?ie=UTF8&amp;amp;track=006&amp;amp;disc=001"&gt;Such a failure to strike the ball is, bizarrely enough,&amp;nbsp;called a "strike"&lt;/A&gt;, and counts against the batter;&amp;nbsp;three strikes and the batter is out.&amp;nbsp;But what if the batter fails to swing at all? If the umpire decides that the pitch was "inside the &lt;A class="" href="http://en.wikipedia.org/wiki/Strike_zone" mce_href="http://en.wikipedia.org/wiki/Strike_zone"&gt;strike zone&lt;/A&gt;" then the pitch counts as a strike against the batter. If the pitch was outside the strike zone then the pitch counts as a "ball" (another bizarre and confusing name; obviously the object pitched&amp;nbsp;is also called a ball). If the pitcher pitches four "balls" before the batter accumulates three "strikes" then the batter gets to "walk" to first base for free. (At least the walk is sensibly named.)&lt;/P&gt;
&lt;P&gt;Formally, the strike zone is reasonably well-defined by the rules (though as the Wikipedia article linked to above indicates, there are some subtle points left out of the definition.) But the formal definition is actually irrelevant; the rules of baseball also state that &lt;EM&gt;a strike is any pitch that the umpire says is a strike&lt;/EM&gt;. Umpires are given wide lattitude to declare what is a strike, and there are no appeals allowed.&lt;/P&gt;
&lt;P&gt;And hence the fundamental disagreement between&amp;nbsp;the three umpires. The first umpire believes that&amp;nbsp;whether a pitch was in the strike zone or not is a &lt;EM&gt;fact&lt;/EM&gt; about an objective reality, and that the call&amp;nbsp;is a sometimes-imperfect subjective&amp;nbsp;judgment about that reality. The second umpire seems to be basically agreeing with the objective, materialist stance of the first umpire, and simply&amp;nbsp;bragging about having 100% accuracy in judgment. The third umpire's position is radically different from the first two: that the rules of baseball say that &lt;EM&gt;regardless &lt;/EM&gt;of the objective reality of the path of the baseball, what &lt;EM&gt;makes&lt;/EM&gt; a pitch into a ball or a strike &lt;EM&gt;is the umpire's call&lt;/EM&gt;, no more, no less.&lt;/P&gt;
&lt;P&gt;I think about the three umpires a lot. The C# language has a clear and mostly unambiguous definition of "the strike zone"; the specification should in theory allow us to classify &lt;EM&gt;any&lt;/EM&gt; finite set of finite strings of text into either "a legal C# program" or "not a legal C# program". As a &lt;EM&gt;spec author&lt;/EM&gt;, I take the third umpire's position: what the spec says is the definition of what is legal, end of story. But as an all-too&amp;nbsp;fallible&amp;nbsp;&lt;EM&gt;compiler writer&lt;/EM&gt;, I take the first umpire's position: the compiler calls 'em as it sees 'em. Sometimes an illegal program accidentally (or deliberately; we implement a small number of extensions to the formal C# language) makes it through the compiler. And sometimes a legal program is incorrectly flagged as an error, or cannot be successfully compiled because it causes the compiler to run out of stack space or some other resource. (Also, though I believe that the compiler always in theory terminates, there are ways to build short C# programs that take exponentially long to analyze, making the compiler a sometimes&amp;nbsp;&lt;EM&gt;impractical&lt;/EM&gt; tool for deciding correctness.) But we calls 'em as we sees 'em, and if we get it wrong, then that's a bug.&lt;/P&gt;
&lt;P&gt;But as a practical matter for our customers, the compiler is more like the third umpire: the arbiter of correctness, with no appeal. And of course I haven't even begun to consider the runtime aspects of correctness! Not only should the compiler decide what programs are legal, it should also generate correct code for every legal program. And again, the code generator plus the CLR's verifier and jitter&amp;nbsp;act like our third umpire; the &lt;EM&gt;de facto&lt;/EM&gt; arbiter of what "the right behaviour" actually is.&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=9917417" width="1" height="1"&gt;</content><author><name>EricLippert</name><uri>http://blogs.msdn.com/members/EricLippert.aspx</uri></author><category term="C#" scheme="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx" /><category term="baseball" scheme="http://blogs.msdn.com/ericlippert/archive/tags/baseball/default.aspx" /></entry><entry><title>Simple names are not so simple, Part Two, plus, volcanoes and fried foods</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/ericlippert/archive/2009/11/05/simple-names-are-not-so-simple-part-two.aspx" /><id>http://blogs.msdn.com/ericlippert/archive/2009/11/05/simple-names-are-not-so-simple-part-two.aspx</id><published>2009-11-05T14:52:00Z</published><updated>2009-11-05T14:52:00Z</updated><content type="html">&lt;DIV class=mine&gt;
&lt;P&gt;I've returned from a brief&amp;nbsp;vacation, visiting friends on the island of Maui. I'd never been to that part of the world before. Turns out, it's a small island in the middle of the Pacific&amp;nbsp;Ocean, entirely made out of volcanoes.&amp;nbsp;Weird!&amp;nbsp;But delightful.&lt;/P&gt;
&lt;P&gt;The most impressive thing about the Hawaiian Islands for me was just how obvious were --&amp;nbsp;even to my completely untrained eyes&amp;nbsp;-- the geomechanical and fluvial processes which shaped the landscape. The mountains and craters and river valleys and red sand beaches and easily-fractured rocks were very different from the (also somewhat volcanic) much older mountainous landscape I've lived in for the past decade.&lt;/P&gt;
&lt;P&gt;Also quite amusing to me was learning to read and pronounce Hawaiian place names. It is all very logical once you know the system; before long I could easily&amp;nbsp;pronounce signs like WAINAPANAPA STATE PARK -- wa-ee-napa-napa&amp;nbsp;--&amp;nbsp;or PUUNENE AVENUE --&amp;nbsp;pu-oo-nay-nay&amp;nbsp;-- or MAILIBEHANAMONOTANA STREET&amp;nbsp;-- "Miley-Stewart-is-really-Hannah-Montana".&lt;/P&gt;
&lt;P&gt;Many thanks to K and R and D for putting me and Leah up for a week; if you're going to Hawai'i and can stay with locals, I highly recommend it, particularly if they are awesome people. Everyone in Maui was awesome, with the exception of the rangers at (stunningly beautiful, even for Maui) Wa'inapanapa State Park, who are apparently consistently grumpy. As one Hawaiian, himself in the camping sector of the economy put it to me, "They do not have&lt;EM&gt; the big aloha&lt;/EM&gt;".&lt;/P&gt;
&lt;P&gt;The most &lt;EM&gt;amusing&lt;/EM&gt; encounter was on the Hana Highway. There are numerous little stops along the way, where someone has erected a hut or parked a trailer and is selling coconuts, smoothies, banana bread, and so on.&amp;nbsp;Hand-lettered signs, stunning natural beauty, middle of nowhere, you get the picture I'm sure. At one of the larger such stops there was a young fellow, probably in his late twenties, serving a variety of fried foods. It was&amp;nbsp;mostly traditional American-style Chinese food, but also he had french fries, fish'n'chips, and so on. He was clearly not a native speaker of English, but spoke understandably with a strong accent. We were waiting behind a middled-aged woman with a typically&amp;nbsp;midwestern American accent. Their conversation went something like this:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Her:&lt;/STRONG&gt; I'm not very hungry, can I just get the fish without the chips?&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Him, not quite following her:&lt;/STRONG&gt; Half order?&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Her, louder&lt;/STRONG&gt;: How much without the fries?&lt;/P&gt;
&lt;P&gt;This went back and forth for some time, both sides becoming increasingly frustrated by the communication breakdown, until:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Her, even&amp;nbsp;louder&lt;/STRONG&gt;: Can I speak to your manager?&lt;/P&gt;
&lt;P&gt;Leah and K and I silently&amp;nbsp;&lt;EM&gt;boggled&lt;/EM&gt; -- there is no other word for it -- at each other for a moment. Where on earth did she imagine that&amp;nbsp;a&amp;nbsp;&lt;EM&gt;manager&lt;/EM&gt; was going to emerge from? There was a counter, behind that, a trailer with a wok in it, behind that, &lt;EM&gt;jungle&lt;/EM&gt;, and behind that, &lt;EM&gt;huge jagged lava rocks&lt;/EM&gt; followed immediately by &lt;EM&gt;the Pacific Ocean&lt;/EM&gt;. And what sort of &lt;EM&gt;management structure&lt;/EM&gt; does she&amp;nbsp;think one really needs to manage&amp;nbsp;a single guy selling pineapple fried rice at the side of a highway? My conclusion: &lt;EM&gt;people have strange beliefs. &lt;/EM&gt;Sometimes their beliefs cause them to leave in a huff with neither fish nor chips, even &lt;EM&gt;when fish and chips are both plentiful and reasonably priced&lt;/EM&gt;. Hopefully she had better luck in Hana.&lt;/P&gt;
&lt;P&gt;Anyway, enough travelogue. Regarding the puzzle from last time: the code is correct, and compiles without issue. I was quite surprised when I first learned that; it certainly looks like&amp;nbsp;it violates our rule about not using the same simple name to mean&amp;nbsp;two different things in&amp;nbsp;one block.&lt;/P&gt;
&lt;P&gt;The key is to understanding why this is legal is&amp;nbsp;that the query comprehensions and foreach loops are specified as &lt;EM&gt;syntactic sugars&lt;/EM&gt; for another program, and it is &lt;EM&gt;that&lt;/EM&gt; program which is actually analyzed for correctness. Our original program:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;static void Main()&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; int[] data = { 1, 2, 3, 1, 2, 1 };&lt;BR&gt;&amp;nbsp; foreach (var m in from m in data orderby m select m)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.Console.Write(m);&lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;is transformed into&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;static void Main()&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; int[] data = { 1, 2, 3, 1, 2, 1 };&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IEnumerator&amp;lt;int&amp;gt; e = ((IEnumerable&amp;lt;int&amp;gt;)(data.OrderBy(m=&amp;gt;m)).GetEnumerator();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; try&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int m;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; while(e.MoveNext())&lt;BR&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;&amp;nbsp; m = (int)(int)e.Current;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.Write(m);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; finally&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (e != null) ((IDisposable)e).Dispose();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;}&lt;BR&gt;&amp;nbsp;&lt;BR&gt;&lt;/SPAN&gt;There are five usages of m in this transformed program; it is:&lt;/P&gt;
&lt;P&gt;1) declared as the formal parameter of a lambda.&lt;BR&gt;2) used in the body of the lambda; here it refers to the formal parameter.&lt;BR&gt;3) declared as a local variable&lt;BR&gt;4) written to in the loop; here it refers to the local variable&lt;BR&gt;5) read from in the loop; here it refers to the local variable&lt;/P&gt;
&lt;P&gt;Is there any usage of a local variable before its declaration? No. &lt;/P&gt;
&lt;P&gt;Are there any two declarations that have the same name in the same declaration space? It would appear so. The body of Main defines a local variable declaration space, and clearly the body of Main contains, indirectly, two declarations for m, one as a formal lambda parameter and one as a local. But I said last time that local variable declaration spaces have special rules for determining overlaps. It is illegal for a local variable declaration space to directly contain a declaration such that another nested local variable declaration space contains a declaration of the same name. But an outer declaration space which indirectly contains two such declarations is not&amp;nbsp; an error. So in this case, no, there are no local variable declarations spaces which directly contain a declaration for m, such that a nested local variable declaration space also directly contains a declaration for m. Our two local variable declarations spaces which directly contain a declaration for m do not overlap anywhere.&lt;/P&gt;
&lt;P&gt;Is there any declaration space which contains two inconsistent usages of the simple name m? Yes, again, the outer block of Main contains two inconsistent usages of m. But again, this is not relevant. The question is whether any declaration space directly containing m has an inconsistent usage. Again, we have two declaration spaces but they do not overlap each other, so there's no problem here either.&lt;/P&gt;
&lt;P&gt;The thing which makes this legal, interestingly enough, is the generation of the loop variable declaration logically within the try block. Were it to be generated outside the try block then this would be a violation of the rule about inconsistent usage of a simple name throughout a declaration space.&lt;BR&gt;&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9909324" width="1" height="1"&gt;</content><author><name>EricLippert</name><uri>http://blogs.msdn.com/members/EricLippert.aspx</uri></author><category term="C#" scheme="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx" /><category term="Puzzles" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Puzzles/default.aspx" /><category term="Dialogue" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Dialogue/default.aspx" /><category term="declaration spaces" scheme="http://blogs.msdn.com/ericlippert/archive/tags/declaration+spaces/default.aspx" /><category term="scope" scheme="http://blogs.msdn.com/ericlippert/archive/tags/scope/default.aspx" /><category term="customer service" scheme="http://blogs.msdn.com/ericlippert/archive/tags/customer+service/default.aspx" /><category term="Simple Names" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Simple+Names/default.aspx" /><category term="maui" scheme="http://blogs.msdn.com/ericlippert/archive/tags/maui/default.aspx" /></entry><entry><title>Simple names are not so simple</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/ericlippert/archive/2009/11/02/simple-names-are-not-so-simple.aspx" /><id>http://blogs.msdn.com/ericlippert/archive/2009/11/02/simple-names-are-not-so-simple.aspx</id><published>2009-11-02T14:23:00Z</published><updated>2009-11-02T14:23:00Z</updated><content type="html">&lt;DIV class=mine&gt;
&lt;P&gt;C# has many rules that are designed to prevent some common sources of bugs and encourage good programming practices. So many, in fact, that it is often quite confusing to sort out exactly which rule has been violated. I thought I might spend some time talking about what the different rules are. We'll finish up with a puzzle.&lt;/P&gt;
&lt;P&gt;To begin with, it will be vital to understand &lt;A href="http://blogs.msdn.com/ericlippert/archive/2009/08/03/what-s-the-difference-part-two-scope-vs-declaration-space-vs-lifetime.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2009/08/03/what-s-the-difference-part-two-scope-vs-declaration-space-vs-lifetime.aspx"&gt;the difference between &lt;EM&gt;scope&lt;/EM&gt; and &lt;EM&gt;declaration space&lt;/EM&gt;&lt;/A&gt;. To refresh your memory of my earlier article: the &lt;EM&gt;scope&lt;/EM&gt; of an entity is &lt;EM&gt;the region of text in which that entity may be referred to by its unqualified name&lt;/EM&gt;. A &lt;EM&gt;declaration space&lt;/EM&gt; is a region of text in which &lt;EM&gt;no two things may have the same name &lt;/EM&gt;(with an exception for methods which differ by signature.) A "local variable declaration space" is a particular kind of declaration space used for declaring local variables; local variable declaration spaces have special rules for determining when they overlap.&lt;/P&gt;
&lt;P&gt;The next thing that you have to understand to make any sense o this is what a "simple name" is. A &lt;EM&gt;simple name&lt;/EM&gt; is always either just a plain identifier, like "x", or, in some cases, a plain identifier followed by a type argument list, like "Frob&amp;lt;int, string&amp;gt;". &lt;/P&gt;
&lt;P&gt;Lots of things are treated as "simple names" by the compiler: local variable declarations, lambda parameters, and so on, always have the first form of simple name in their declarations. When you say "Console.WriteLine(x);" the "Console" and "x" are simple names but the "WriteLine" is not. Confusingly, there are some textual entities which have the form of simple names, but are not treated as simple names by the compiler. We might talk about some of those situations in later fabulous adventures.&lt;/P&gt;
&lt;P&gt;So, without further ado, here are some relevant rules which are frequently confused. It's rules 3 and 4 that people find particularly confusing.&lt;/P&gt;
&lt;P&gt;1) It is illegal to refer to a local variable before its declaration. (This seems reasonable I hope.)&lt;BR&gt;2) It is illegal to have two local variables of the same name in the same local variable declaration space or nested local variable declaration spaces.&lt;BR&gt;3) Local variables are in scope throughout the entire block in which the declaration occurs. This is in contrast with C++, in which local variables are in scope in their block only at points after the declaration.&lt;BR&gt;4) For every occurrence of a simple name, whether in a declaration or as part of an expression, all uses of that simple name within the immediately enclosing local variable declaration space must refer to the same entity.&lt;/P&gt;
&lt;P&gt;The purpose of all of these rules is to prevent the class of bugs in which the reader/maintainer of the code is tricked into believing they are referring to one entity with a simple name, but are in fact accidentally referring to another entity entirely. These rules are in particular designed to prevent nasty surprises when performing what ought to be safe refactorings. &lt;/P&gt;
&lt;P&gt;Consider a world in which we did not have rules 3 and 4. In that world, this code would be legal:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;class C&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; int x;&lt;BR&gt;&amp;nbsp; void M()&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 100 lines of code&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; x = 20; // means "this.x";&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(x); // means "this.x"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 100 lines of code&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int x = 10;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(x); // means "local x"&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;This is hard on the person reading the code, who has a reasonable expectation that the two "Console.WriteLine(x)" lines do in fact both print out the contents of the same variable. But it is particularly nasty for the maintenance programmer who wishes to impose a reasonable coding standard upon this body of code. "Local variables are declared at the top of the block where they're used" is a reasonable coding standard in a lot of shops. But changing the code to:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;class C&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; int x;&lt;BR&gt;&amp;nbsp; void M()&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int x;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 100 lines of code&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; x = 20; // no longer means "this.x";&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(x); // no longer means "this.x"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 100 lines of code&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; x = 10;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(x); // means "local x"&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;} &lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;changes the meaning of the code! We wish to discourage authoring of multi-hundred-line methods, but making it harder and more error-prone to refactor them into something cleaner is not a good way to achieve that goal.&lt;/P&gt;
&lt;P&gt;Notice that the original version of this program, rule 3 means that the program violates rule 1 -- the first usage of "x" is treated as a reference to the local before it is declared. The fact that it violates rule 1 because of rule 3 is precisely what prevents it from being a violation of rule 4! The meaning of "x" is consistent throughout the block; it always means the local, and therefore is sometimes used before it is declared. If we scrapped rule 3 then this would be a violation of rule 4, because we would then have two inconsistent meanings for the simple name "x" within one block.&lt;/P&gt;
&lt;P&gt;Now, these rules do not mean that you can refactor willy-nilly. We can still construct situations in which similar refactorings fail. For example:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;class C&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; int x;&lt;BR&gt;&amp;nbsp; void M()&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 100 lines of code&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; x = 20; // means "this.x";&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(x); // means "this.x"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 100 lines of code&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int x = 10;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(x); // means "local x"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;This is perfectly legal. We have the same simple name being used two different ways in two different blocks, but the immediately enclosing block of each usage does not overlap that of any other usage. The local variable is in scope throughout its immediately enclosing block, but that block does not overlap the block above. In this case, it is safe to refactor the declaration of the local to the top of its block, but not safe to refactor the declaration to the top of the outermost block; that would change the meaning of "x" in the first block. Moving a declaration up is almost always a safe thing to do; moving it out is not necessarily safe. &lt;/P&gt;
&lt;P&gt;Now that you know all that, here's a puzzle for you, a puzzle that I got completely wrong the first time I saw it:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;using System.Linq;&lt;BR&gt;class Program&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; static void Main()&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int[] data = { 1, 2, 3, 1, 2, 1 };&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (var m in from m in data orderby m select m)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.Console.Write(m);&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;It certainly looks like name "m" is being used multiple times to mean different things. Is this program legal? If yes, why do the rules for not re-using simple names&amp;nbsp;not apply? If no, precisely what rule has been violated?&amp;nbsp; &lt;/P&gt;
&lt;P&gt;[Eric is on vacation; this posting was pre-recorded.]&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9909292" width="1" height="1"&gt;</content><author><name>EricLippert</name><uri>http://blogs.msdn.com/members/EricLippert.aspx</uri></author><category term="C#" scheme="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx" /><category term="Puzzles" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Puzzles/default.aspx" /><category term="Language Design" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Language+Design/default.aspx" /><category term="declaration spaces" scheme="http://blogs.msdn.com/ericlippert/archive/tags/declaration+spaces/default.aspx" /><category term="scope" scheme="http://blogs.msdn.com/ericlippert/archive/tags/scope/default.aspx" /><category term="Simple Names" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Simple+Names/default.aspx" /><category term="local variables" scheme="http://blogs.msdn.com/ericlippert/archive/tags/local+variables/default.aspx" /><category term="refactoring" scheme="http://blogs.msdn.com/ericlippert/archive/tags/refactoring/default.aspx" /></entry><entry><title>I have a Fit, but a lack of Focus.</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/ericlippert/archive/2009/10/29/i-have-a-fit-but-a-lack-of-focus.aspx" /><id>http://blogs.msdn.com/ericlippert/archive/2009/10/29/i-have-a-fit-but-a-lack-of-focus.aspx</id><published>2009-10-29T13:54:00Z</published><updated>2009-10-29T13:54:00Z</updated><content type="html">&lt;DIV class=mine&gt;
&lt;P&gt;Here's a statement I read the other day about making comparisons between objects of reference type in C#:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Object.ReferenceEquals(x,y) returns true if and only if x and y refer to the same object.&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;True or false?&lt;/P&gt;
&lt;P&gt;My wife Leah recently acquired a Honda Fit, thanks to the imminant failure of the automatic transmission solenoids in her aged Honda Civic. The back seats in the Fit fold down flat. You can fit a llama or a whole pile of hula hoops or whatever into that thing. It's quite handy. Not what I would call a powerful engine by any means, but for quick trips around town, it certainly gets the job done.&lt;/P&gt;
&lt;P&gt;Since we were married when she bought the car, and we continue to be married, what's mine is hers and what's hers is mine. So if x = Eric's Honda Fit, and y = Leah's Honda Fit, then x and y are "reference equals". Those two things refer to the same object, viz, the shiny black object full of llamas and hula hoops in my driveway.&lt;/P&gt;
&lt;P&gt;Now, we could have bought a different car. Say, a Ford Focus. But we did not. We own a total of zero Ford Foci. Suppose I said that x = Eric's Ford Focus, and y = Leah's Ford Focus. What's the sensible way to characterize the nature of x and y? Do we say that x and y refer to the same Ford Focus, namely that they refer to the Ford Focus&amp;nbsp;that does not exist? The mind boggles at the repugnant and paradoxical implication that there exists a Ford Focus that is the Ford Focus&amp;nbsp;that does not exist! (*) Rather, the right way to characterize this is to say that neither x nor y refer to any object. They're "null references" -- references that do not have any referent, but rather, capture the notion of "a lack of referent".&lt;/P&gt;
&lt;P&gt;And that's why it's incorrect to say that Object.ReferenceEquals(x,y) returns true&amp;nbsp;&lt;STRONG&gt;if and only if&lt;/STRONG&gt;&amp;nbsp;x and y refer to the &lt;STRONG&gt;same object&lt;/STRONG&gt;.If x and y both do not refer to any object, then clearly they do not&lt;EM&gt; refer to&lt;/EM&gt; &lt;EM&gt;the same object&lt;/EM&gt;, because&amp;nbsp;&lt;EM&gt;neither refers to an object in the first place&lt;/EM&gt;. The correct way to characterize the behaviour of reference equality is&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Object.ReferenceEquals(x,y) returns true&amp;nbsp;if and only if&amp;nbsp;either x and y refer to the same object, &lt;EM&gt;or x and y are both null references.&lt;/EM&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;***********&lt;/P&gt;
&lt;P&gt;(*) And yet I am a fan of the "null object pattern". Life is just full of these little contradictions.&lt;/P&gt;
&lt;P mce_keep="true"&gt;[Eric is on vacation this week; this posting is pre-recorded.]&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9908258" width="1" height="1"&gt;</content><author><name>EricLippert</name><uri>http://blogs.msdn.com/members/EricLippert.aspx</uri></author><category term="C#" scheme="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx" /><category term="myths" scheme="http://blogs.msdn.com/ericlippert/archive/tags/myths/default.aspx" /><category term="reference equality" scheme="http://blogs.msdn.com/ericlippert/archive/tags/reference+equality/default.aspx" /><category term="Honda fit" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Honda+fit/default.aspx" /><category term="Ford Focus" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Ford+Focus/default.aspx" /></entry><entry><title>Some new videos</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/ericlippert/archive/2009/10/26/some-new-videos.aspx" /><id>http://blogs.msdn.com/ericlippert/archive/2009/10/26/some-new-videos.aspx</id><published>2009-10-26T13:17:00Z</published><updated>2009-10-26T13:17:00Z</updated><content type="html">&lt;DIV class=mine&gt;
&lt;P&gt;Somehow it has happened again; people just keep on recording videos of me and putting them on the internet. &lt;/P&gt;
&lt;P&gt;In these videos you find out what I look like when lit from above and behind. Kinda spooky. We should have made the room entirely dark and held a flashlight underneath my face. That would be, like, &lt;A class="" href="http://xenon.xe.net/inthumor/ih_026.htm" mce_href="http://xenon.xe.net/inthumor/ih_026.htm"&gt;ten times scarier&lt;/A&gt;. Anyway, if you're interested in me blathering on about my favourite feature in C# 4, covariance and contravariance of interface and delegate types, here are two little demo videos: &lt;A class="" href="http://msdn.microsoft.com/en-us/vcsharp/ee672314.aspx" mce_href="http://msdn.microsoft.com/en-us/vcsharp/ee672314.aspx"&gt;Part One&lt;/A&gt;, &lt;A class="" href="http://msdn.microsoft.com/en-us/vcsharp/ee672319.aspx" mce_href="http://msdn.microsoft.com/en-us/vcsharp/ee672319.aspx"&gt;Part Two&lt;/A&gt;. (There seems to be some minor sound sync issues here and there, but it's not really a problem; most of the&amp;nbsp;audio is voice-over.)&lt;/P&gt;
&lt;P&gt;Charlie has been crazy busy getting these little videos together; here are some more of his recent efforts, including some good ones from my colleagues Chris and Sam talking about all the other far more awesome features of C# 4.0: dynamic interop, improved interop with Office, named and optional parameters, and so on. Links to all of our recent videos are here: &lt;A href="http://blogs.msdn.com/charlie/archive/2009/10/19/community-convergence-lvi.aspx" mce_href="http://blogs.msdn.com/charlie/archive/2009/10/19/community-convergence-lvi.aspx"&gt;http://blogs.msdn.com/charlie/archive/2009/10/19/community-convergence-lvi.aspx&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;Have an amusing and safe Hallowe'en -- I'll be going to Hallowe'en parties on a small island this year, just for a change of pace.&lt;/P&gt;
&lt;P mce_keep="true"&gt;[Eric is on vacation this week; this posting was pre-recorded]&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9911473" width="1" height="1"&gt;</content><author><name>EricLippert</name><uri>http://blogs.msdn.com/members/EricLippert.aspx</uri></author><category term="C#" scheme="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx" /><category term="Video" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Video/default.aspx" /><category term="Covariance and Contravariance" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/default.aspx" /><category term="C# 4.0" scheme="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_+4.0/default.aspx" /></entry><entry><title>Begging the question</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/ericlippert/archive/2009/10/22/begging-the-question.aspx" /><id>http://blogs.msdn.com/ericlippert/archive/2009/10/22/begging-the-question.aspx</id><published>2009-10-22T13:23:00Z</published><updated>2009-10-22T13:23:00Z</updated><content type="html">&lt;DIV class=mine&gt;
&lt;P&gt;In my last post I described the syllogism "&lt;EM&gt;Photogenic people look good in photograps; Michelle Pfeiffer is photogenic; therefore, Michelle Pfeiffer looks good in photographs&lt;/EM&gt;" as "begging the question". A few people commented on that, so I thought I'd address this point of English usage.&lt;/P&gt;
&lt;P&gt;In modern usage, "begging the question" has come to mean nothing more than "&lt;EM&gt;the situation suggests that an obvious question to raise at this time is blah blah blah&lt;/EM&gt;."&amp;nbsp;For example, "&lt;EM&gt;The global financial meltdown begs the question: was there insufficient federal oversight of the American mortgage industry?&lt;/EM&gt;"&amp;nbsp;Though this usage is certainly common in civic discourse and the media, it is&amp;nbsp;entirely a modern departure&amp;nbsp;from the historic usage of the phrase. I try to eschew this modern usage when I say "begs the question".&lt;/P&gt;
&lt;P&gt;"Begs the question" is also sometimes used to mean "this argument raises additional questions which require additional investigation before we can accept the argument". Though this is considerably &lt;EM&gt;closer&lt;/EM&gt; to the traditional definition of the phrase, this is also not exactly what I mean.&lt;/P&gt;
&lt;P&gt;When I say "begs the question",&amp;nbsp;I mean it in the traditional sense of "this argument is fallacious because it takes as a premise an assumption which is at least as strong as the thing being proven, and is therefore an unwarranted assumption."&lt;/P&gt;
&lt;P&gt;Let me give you another example of question begging, in the traditional sense, which might be more clear.&lt;/P&gt;
&lt;P&gt;Suppose I asked "why&amp;nbsp;are diamonds very hard but&amp;nbsp;butter is very soft?" and you answered "diamond and butter are both made out of atoms; the atoms of diamonds are hard and the atoms of butter are soft." You would have begged the question; your answer to my question "why are some things hard and some things soft" is "because some things are made out of stuff that is hard and some things are made out of stuff that is soft" -- that is, you've avoided answering the question&amp;nbsp;by providing&amp;nbsp;an "explanation" that itself cannot be understood without answering the original question -- namely, &lt;EM&gt;why&lt;/EM&gt; is some stuff hard and some stuff soft? This pseudo-explanation has no predictive power; it doesn't tell us anything new, it just circles back on itself. The explanatory assumption -- that some atoms are hard and some atoms are soft -- is &lt;EM&gt;stronger&lt;/EM&gt; than&amp;nbsp;the thing we are trying to investigate -- the hardness and softness of two substances.&lt;/P&gt;
&lt;P&gt;A non-question-begging answer would be "diamond and butter are both made of atoms; the atoms of a diamond are all identical and arranged in a stable, rigid lattice where every point in the lattice is reinforced by a strong bond to four other points. The atoms of butter are a disorganized collection of many different atoms grouped into different kinds of relatively complex molecules; though the molecules themselves are quite strong, each molecule of butter holds weakly to each other molecule. It takes only a small force to disrupt the loose arrangement of butter molecules but a very large force to disrupt the strong arrangement of diamond atoms. We perceive this difference in required force as 'hardness' on the human scale, but in fact it is a property that arises from the sub-microscopic-scale properties of each substance."&lt;/P&gt;
&lt;P&gt;Now, this explanation does *raise* more questions. It raises questions like "why are some lattices strong and some weak?" and "why are some objects composed of many different kinds of atoms organized into molecules, and some composed of just one atom?" Question-begging is not the act of raising more questions. &lt;EM&gt;Every&lt;/EM&gt; good explanation raises more questions. What makes this explanation a good one is that&amp;nbsp;it is &lt;EM&gt;testable&lt;/EM&gt; and has &lt;EM&gt;predictive power&lt;/EM&gt;; we can investigate the hardness or softness of other substances, and make predictions about what sorts of atomic structures they will have -- or, vice versa, we can look at an atomic structure and try to figure out from it how hard the substance will be. We can invent other techniques for determining atomic structure, like x-ray diffraction crystallography or spectroscopic analysis, and use those to cross-check our "atomic theory of hardness".&lt;/P&gt;
&lt;P&gt;But the "because she's photogenic" pseudo-explanation is clearly question-begging. Why does she look so good? Because she's photogenic. Why is she photogenic? Because she looks so good. We have learned nothing about photogenicity (or the lovely Ms. Pfeiffer). &lt;/P&gt;
&lt;P&gt;Similarly, if you ask "why is this code thread-safe?" and the answer is "because it can be correctly called on multiple threads", we've begged the question. Why is it thread-safe? Because it's correct. Why is it correct? Because it's thread-safe. Again, we have learned nothing about the nature of thread safety. &lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9909508" width="1" height="1"&gt;</content><author><name>EricLippert</name><uri>http://blogs.msdn.com/members/EricLippert.aspx</uri></author><category term="English Usage" scheme="http://blogs.msdn.com/ericlippert/archive/tags/English+Usage/default.aspx" /><category term="Michelle Pfeiffer" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Michelle+Pfeiffer/default.aspx" /><category term="Begging the question" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Begging+the+question/default.aspx" /></entry><entry><title>What is this thing you call "thread safe"?</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/ericlippert/archive/2009/10/19/what-is-this-thing-you-call-thread-safe.aspx" /><id>http://blogs.msdn.com/ericlippert/archive/2009/10/19/what-is-this-thing-you-call-thread-safe.aspx</id><published>2009-10-19T13:50:00Z</published><updated>2009-10-19T13:50:00Z</updated><content type="html">&lt;DIV class=mine&gt;
&lt;P&gt;&lt;STRONG&gt;Caveat: I am not an expert on multi-threading programming.&lt;/STRONG&gt; In fact, I wouldn't even say that I am &lt;EM&gt;competent&lt;/EM&gt; at it. My whole career, I've needed to write code to spin up a secondary worker thread probably less than half a dozen times. So take everything I say on the subject with some skepticism.&lt;/P&gt;
&lt;P&gt;A question I'm frequently asked: "&lt;EM&gt;is this code &lt;STRONG&gt;thread safe&lt;/STRONG&gt;?&lt;/EM&gt;" To answer the question, clearly we need to know what "thread safe" means.&lt;/P&gt;
&lt;P&gt;But before we get into that, there's something I want to clear up first. A question I am less frequently asked is "&lt;EM&gt;Eric, why does Michelle Pfeiffer always look so good in photographs?&lt;/EM&gt;"&amp;nbsp;To help answer this pressing question, I&amp;nbsp;consulted &lt;A class="" href="http://en.wikipedia.org/wiki/Photogenic" mce_href="http://en.wikipedia.org/wiki/Photogenic"&gt;Wikipedia&lt;/A&gt;:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;EM&gt;"A&amp;nbsp;&lt;B&gt;photogenic&lt;/B&gt; subject&amp;nbsp;is a subject that usually appears physically attractive or striking in photographs."&lt;/EM&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Why&amp;nbsp;does Michelle Pfeiffer always look so good in photographs? &lt;STRONG&gt;&lt;EM&gt;Because she's photogenic&lt;/EM&gt;.&lt;/STRONG&gt; Obviously.&lt;/P&gt;
&lt;P&gt;Well, I'm glad we've cleared up that mystery, but I seem to have wandered somehwat from the subject at hand. Wikipedia is &lt;A class="" href="http://en.wikipedia.org/wiki/Thread_safety" mce_href="http://en.wikipedia.org/wiki/Thread_safety"&gt;just as helpful in defining thread safety&lt;/A&gt;:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;EM&gt;&amp;nbsp;"A piece of code is &lt;B&gt;thread-safe&lt;/B&gt; if it functions correctly during simultaneous execution by multiple threads."&lt;/EM&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;As with photogenicity, this&amp;nbsp;is obvious question-begging. When we ask "is this code &lt;EM&gt;thread safe&lt;/EM&gt;?" all we are really asking is "is this code &lt;EM&gt;correct&lt;/EM&gt; &lt;EM&gt;when called in a particular manner&lt;/EM&gt;?"&amp;nbsp;So how do we determine if the code is correct? &lt;STRONG&gt;We haven't actually explained anything here.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Wikipedia goes on:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P mce_keep="true"&gt;&lt;EM&gt;"In particular, it must satisfy the need for multiple threads to access the same shared data, ..."&lt;/EM&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P mce_keep="true"&gt;This seems fair; this scenario is almost always what people mean when they talk about thread safety. But then:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P mce_keep="true"&gt;&lt;EM&gt;"...and the need for a shared piece of data to be accessed by only one thread at any given time."&lt;/EM&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P mce_keep="true"&gt;Now we're talking about techniques for &lt;EM&gt;creating&lt;/EM&gt; thread safety, not &lt;EM&gt;defining&lt;/EM&gt; what thread safety means. Locking data so that it can only be accessed by one thread at a time is just one possible&amp;nbsp;technique for creating thread safety; it is not itself the definition of thread safety.&lt;/P&gt;
&lt;P mce_keep="true"&gt;My point is not that the definition is &lt;EM&gt;wrong&lt;/EM&gt;; as informal definitions of thread safety&amp;nbsp;go, this one is not terrible.&amp;nbsp;Rather, my point is&amp;nbsp;that the&amp;nbsp;definition indicates that the concept itself is &lt;EM&gt;completely vague&lt;/EM&gt; and essentially means nothing more than "behaves correctly in some situations". Therefore, when I'm asked "is this code thread safe?" I always have to push back and ask "what are the &lt;EM&gt;exact&lt;/EM&gt; &lt;EM&gt;threading scenarios&lt;/EM&gt; you are concerned about?" and "exactly what is &lt;EM&gt;correct behaviour&lt;/EM&gt; of the object in every one of those scenarios?"&lt;/P&gt;
&lt;P mce_keep="true"&gt;Communication problems arise when&amp;nbsp;people with different answers to those questions try to communicate about thread safety. For example, suppose I told you that I have a "threadsafe mutable queue" that you can use in your program.&amp;nbsp;You then cheerfully write the following code that runs on one thread while another thread is busy adding and removing items from the mutable queue:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P mce_keep="true"&gt;if (!queue.IsEmpty) Console.WriteLine(queue.Peek());&lt;/P&gt;&lt;/SPAN&gt;
&lt;P mce_keep="true"&gt;Your code then crashes when the Peek throws a QueueEmptyException. What is going on here? I&amp;nbsp;said this&amp;nbsp;thing was thread safe, and yet your code is crashing in a multi-threaded scenario.&lt;/P&gt;
&lt;P mce_keep="true"&gt;When I said "the queue is threadsafe" I meant that the queue maintains its internal state consistently no matter what sequence of &lt;EM&gt;individual&lt;/EM&gt; operations are happening on other threads. But I did not mean that you can use my queue in any scenario that requires &lt;EM&gt;logical consistency maintained across multiple operations in a sequence&lt;/EM&gt;. In short, my opinion of "correct behaviour" and your opinion of the same differed because what we thought of as the relevant scenario was completely different. I care only about not crashing, but you care about being able to reason logically about the information returned from each method call.&lt;/P&gt;
&lt;P mce_keep="true"&gt;In this example, you and I are probably&amp;nbsp;talking about different kinds of thread safety. Thread safety of mutable data structures is usually all about ensuring that the operations on the shared data always operate on the &lt;STRONG&gt;most up-to-date&lt;/STRONG&gt; state of the shared data as it mutates, even if that means that a particular combination of operations appears to be &lt;STRONG&gt;logically inconsistent&lt;/STRONG&gt;, as in our example above. Thread safety of immutable data structures is all about ensuring that use of&amp;nbsp;the data across all operations is &lt;STRONG&gt;logically consistent&lt;/STRONG&gt;, at the expense of the fact that you're looking at an&amp;nbsp;immutable&amp;nbsp;snapshot that might be &lt;STRONG&gt;out-of-date&lt;/STRONG&gt;.&lt;/P&gt;
&lt;P mce_keep="true"&gt;The problem here is that the choice about whether to access the first element or not is based on "stale" data. Designing a truly thread-safe mutable data structure in a world where &lt;EM&gt;nothing is allowed to be stale&lt;/EM&gt; can be&amp;nbsp;very difficult. Consider what you'd have to do in order to make the "Peek" operation above actually threadsafe. You'd need a new method:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P mce_keep="true"&gt;if (!queue.Peek(out first)) Console.WriteLine(first);&lt;/P&gt;&lt;/SPAN&gt;
&lt;P mce_keep="true"&gt;Is this "thread safe"? It certainly seems better.&amp;nbsp;But what if after the Peek, a different thread dequeues the queue? Now you're not crashing, but you've changed the behaviour of the previous program considerably. In the previous program, if, after the test there was a dequeue on another thread that changed what the first element was, then you'd either crash or&amp;nbsp;print out the up-to-date first element in the queue. Now you're printing out a &lt;EM&gt;stale&lt;/EM&gt; first element. Is that &lt;EM&gt;correct&lt;/EM&gt;? Not if we &lt;EM&gt;always&lt;/EM&gt; want to operate on up-to-date data!&lt;/P&gt;
&lt;P mce_keep="true"&gt;But wait a moment -- actually, the &lt;EM&gt;previous&lt;/EM&gt; version of the code had this problem as well. What if the dequeue on the other thread happened &lt;EM&gt;after&lt;/EM&gt; the call to Peek succeeded but &lt;EM&gt;before&lt;/EM&gt; the Console.WriteLine call executed? Again, you could be printing out stale data.&lt;/P&gt;
&lt;P mce_keep="true"&gt;What if you want to ensure that you are always printing out up-to-date data? What you really need to make this threadsafe is:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P mce_keep="true"&gt;queue.DoSomethingToHead(first=&amp;gt;{Console.WriteLine(first);});&lt;/P&gt;&lt;/SPAN&gt;
&lt;P mce_keep="true"&gt;Now the queue&amp;nbsp;author and the queue user agree on what the relevant scenarios are, so this is truly threadsafe. Right?&lt;/P&gt;
&lt;P mce_keep="true"&gt;Except... there could be something super-complicated in that delegate. What if whatever is in the delegate happens to cause an event that triggers code to run on another thread, which in turn causes some queue operation to run, which in turn blocks in such a manner that we've produced a deadlock? Is a deadlock "correct behaviour"? And if not, is&amp;nbsp;this method truly "safe"?&lt;/P&gt;
&lt;P mce_keep="true"&gt;Yuck.&lt;/P&gt;
&lt;P mce_keep="true"&gt;By now you take my point I'm sure.&amp;nbsp;As I pointed out earlier, &lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2008/08/19/tasty-beverages.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2008/08/19/tasty-beverages.aspx"&gt;it is unhelpful to say that a building or a hunk of code is "secure" without somehow communicating &lt;STRONG&gt;which&amp;nbsp;threats&lt;/STRONG&gt;&amp;nbsp;the utilized security mechanism are and are not&amp;nbsp;proof against.&lt;/A&gt; Similarly,&amp;nbsp;&lt;STRONG&gt;it is unhelpful to say that code is "thread safe" without somehow communicating what undesirable&amp;nbsp;behaviors the utilized thread safety mechanisms do and do not prevent.&lt;/STRONG&gt; "Thread safety" is nothing more nor less than a code contract, like any other code contract. You agree to talk to an object in a particular manner, and it agrees to give you correct results if you do so; working out exactly what that manner is, and what the correct responses are, is a potentially tough problem.&lt;/P&gt;
&lt;P mce_keep="true"&gt;************&lt;/P&gt;
&lt;P&gt;(*) Yes, I'm aware that if I think something on Wikipedia is wrong, I can change it. There are two reasons why I should not do so.&amp;nbsp;First, as&amp;nbsp;I've already stated I'm not an expert in this area; I leave it to the experts to sort out amongst themselves what the right thing to say here is. And second, my point is not that the Wikipedia page is wrong, but rather that it illustrates that the term itself is&amp;nbsp;vague by nature.&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=9906219" width="1" height="1"&gt;</content><author><name>EricLippert</name><uri>http://blogs.msdn.com/members/EricLippert.aspx</uri></author><category term="C#" scheme="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx" /><category term="Threading" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Threading/default.aspx" /><category term="Immutability" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Immutability/default.aspx" /><category term="Wikipedia" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Wikipedia/default.aspx" /><category term="Michelle Pfeiffer" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Michelle+Pfeiffer/default.aspx" /><category term="Begging the question" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Begging+the+question/default.aspx" /></entry><entry><title>As Timeless As Infinity</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/ericlippert/archive/2009/10/15/as-timeless-as-infinity.aspx" /><id>http://blogs.msdn.com/ericlippert/archive/2009/10/15/as-timeless-as-infinity.aspx</id><published>2009-10-15T13:25:00Z</published><updated>2009-10-15T13:25:00Z</updated><content type="html">&lt;DIV class=mine&gt;
&lt;P&gt;&lt;STRONG&gt;User:&lt;/STRONG&gt; Recently I found out about a peculiar behaviour concerning division by zero in floating point numbers in C#. It does not throw an exception, as with integer division,&amp;nbsp;but rather returns an "infinity". Why is that?&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Eric:&lt;/STRONG&gt; As I've often said, "why" questions are difficult for me&amp;nbsp;to answer. My first attempt at an answer to a "why" question is usually "because that's what the specification says to do"; this time is no different. The C# specification says to do that in section 4.1.6. But we're only doing that because that's what&amp;nbsp;the IEEE standard for floating point arithmetic says to do. We wish to be compliant with the established industry standard. See &lt;A href="http://en.wikipedia.org/wiki/IEEE_754-1985" mce_href="http://en.wikipedia.org/wiki/IEEE_754-1985"&gt;IEEE standard 754-1985&lt;/A&gt; for details. Most floating point&amp;nbsp;arithmetic&amp;nbsp;is done in hardware these days, and most hardware is compliant with this specification.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;User:&lt;/STRONG&gt;&amp;nbsp;It seems to me that division by zero is a bug no matter how you look at it!&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Eric:&lt;/STRONG&gt; Well, since clearly that is not how the members of the IEEE standardization committee looked at it in 1985, your statement that it must be a bug "no matter how you look at it" must be incorrect. Some industry experts do not look at it that way.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;User:&lt;/STRONG&gt;&amp;nbsp;Good point. What motivated this design decision?&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Eric:&lt;/STRONG&gt; I wasn't there; I was busy playing&amp;nbsp;Jumpman on my Commodore 64 at the time. But my educated guess is that &lt;STRONG&gt;it is desirable for all possible operations on all floats to produce a well-defined float result&lt;/STRONG&gt;. Mathematicians would call this a "closure" property; that is, the set of floating point numbers is "closed" over all operations.&lt;/P&gt;
&lt;P&gt;Positive infinity seems like a reasonable choice for dividing a positive number by zero. It seems plausible because of course the limit of 1 / x as x goes to zero (from above)&amp;nbsp;is "positive infinity", so why shouldn't 1/0 be the number "positive infinity"?&lt;/P&gt;
&lt;P&gt;Now, speaking &lt;EM&gt;as a mathematician&lt;/EM&gt;, I find that argument specious. A thing&amp;nbsp;and its limit need not have any particular property in common; it is fallacious to reason that just because, say, a sequence has a particular limit that a fact about the limit is also a fact about the sequence. Mathematically, "positive infinity" (in the sense of a limit of a real-valued function; let's leave transfinite ordinals, hyperbolic geometry, and all of that&amp;nbsp;other stuff out of this discussion)&amp;nbsp;is not a number at all and should not be treated as one; rather, it's a terse way of saying "the limit does not exist because the sequence diverges upwards". &lt;/P&gt;
&lt;P&gt;When we divide by zero, essentially what we are saying is "solve the equation x * 0 = 1"; the solution to that equation is not "positive infinity", it is "I cannot because there is no solution to that equation". It's just the same as asking to solve the equation "x + 1 = x" -- saying "x is positive infinity" is not a solution; there is no solution.&lt;/P&gt;
&lt;P&gt;But speaking &lt;EM&gt;as a practical engineer&lt;/EM&gt; who uses floating point numbers to do an imprecise approximation of ideal arithmetic, this seems like a perfectly reasonable choice. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;User:&lt;/STRONG&gt;&amp;nbsp;But surely it is impossible for the hardware to represent "infinity".&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Eric:&lt;/STRONG&gt; It certainly is possible. You've got 32 bits in a single-precision float; that's over four billion possible floats. All bit patterns of the form &lt;/P&gt;
&lt;P&gt;?11111111??????????????????????? &lt;/P&gt;
&lt;P&gt;are reserved for "not-a-number" values. That's over sixteen million possible NaN combinations. Two of those sixteen million NaN bit patterns are reserved to mean positive and negative infinity. Positive infinity is the bit pattern 01111111100000000000000000000000 and negative infinity is 11111111100000000000000000000000. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;User:&lt;/STRONG&gt;&amp;nbsp;Do all languages and applications use this convention of division-by-zero-becomes-infinity?&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Eric: &lt;/STRONG&gt;No.&amp;nbsp;For example, C#&amp;nbsp;and JScript do but&amp;nbsp;VBScript does not. VBScript gives an error if you do that.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;User:&lt;/STRONG&gt;&amp;nbsp;Then how do language implementors get the desired behaviour for each language if these semantics are implemented by the hardware?&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Eric: &lt;/STRONG&gt;There are two basic techniques. First, many chips which implement this standard allow&amp;nbsp;the programmer&amp;nbsp;to make float division by zero an exception rather than an infinity. On the 80x87 chip, for example, you can use bit two of the precision control register to determine whether division by zero returns an infinity or&amp;nbsp;throws a hardware exception. &lt;/P&gt;
&lt;P&gt;Second, if you don't want it to be a hardware exception but do want it to be a software exception, then you can check bit two of the status register after each division;&amp;nbsp;it records whether there was&amp;nbsp;a recent divide-by-zero event. &lt;/P&gt;
&lt;P&gt;The latter strategy is used by VBScript; after we perform a division operation we check to see whether the status register recorded a divide-by-zero operation; if it did, then the VBScript runtime creates a divide-by-zero error and the usual VBScript error management&amp;nbsp;process takes over, same as any other error.&lt;/P&gt;
&lt;P&gt;Similar bits exist for other operations that seem like they might be better treated as exceptions, like numeric overflow.&lt;/P&gt;
&lt;P&gt;The existence of the "hardware exception" bits creates problems for the modern&amp;nbsp;language implementor, because we are now often in a world where code written in multiple languages from multiple vendors is running in the same process. Control bits on hardware are the ultimate "global state", and we all know how irksome it is to have global, public state that random code can stomp on. &lt;/P&gt;
&lt;P&gt;For example: I might be misremembering some details, but I seem to recall that Delphi-authored controls set the "overflows cause exceptions" bit. That is, the Delphi implementors did not use the VBScript strategy of "try it, allow it to succeed, and check to see whether the&amp;nbsp;overflow bit was set in the status register". Rather, they used the "make the hardware throw an exception and then catch the exception" strategy. This is deeply unfortunate.&amp;nbsp;When a VBScript script&amp;nbsp;calls a Delphi-authored control, the control flips the bit to force exceptions but it never "unflips" it. If, later on in the script, the VBScript program does an overflow, then we get an unhandled hardware exception because the bit is still set, even though the Delphi control might be long gone! I fixed that by saving away the state of the control register before calling into a component and restoring it when control returns. That's not ideal, but there's not much else we can do.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;User:&lt;/STRONG&gt;&amp;nbsp;Very enlightening! I will be sure to pass this information along to my coworkers. I would be delighted to see a blog post on this.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Eric: &lt;/STRONG&gt;And here you go!&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=9904452" width="1" height="1"&gt;</content><author><name>EricLippert</name><uri>http://blogs.msdn.com/members/EricLippert.aspx</uri></author><category term="VBScript" scheme="http://blogs.msdn.com/ericlippert/archive/tags/VBScript/default.aspx" /><category term="C#" scheme="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx" /><category term="Floating Point Arithmetic" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Floating+Point+Arithmetic/default.aspx" /><category term="Dialogue" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Dialogue/default.aspx" /><category term="Language Design" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Language+Design/default.aspx" /><category term="exception handling" scheme="http://blogs.msdn.com/ericlippert/archive/tags/exception+handling/default.aspx" /><category term="Delphi" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Delphi/default.aspx" /></entry><entry><title>Absence of evidence is not evidence of absence</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/ericlippert/archive/2009/10/12/absence-of-evidence-is-not-evidence-of-absence.aspx" /><id>http://blogs.msdn.com/ericlippert/archive/2009/10/12/absence-of-evidence-is-not-evidence-of-absence.aspx</id><published>2009-10-12T13:51:00Z</published><updated>2009-10-12T13:51:00Z</updated><content type="html">&lt;DIV class=mine&gt;
&lt;P&gt;Today, two more subtly incorrect myths about C#.&lt;/P&gt;
&lt;P&gt;As you probably know, C# requires all local variables to be explicitly assigned before they are read, but assumes that all class instance field variables are initially assigned to default values. An explanation of why that is that I sometimes hear is "&lt;EM&gt;the compiler can easily prove that a local variable is not assigned, but it is much harder to prove that an instance&amp;nbsp;field is not assigned. And since the class's default constructor automatically assigns all instance fields to default values, you don't need to do the analysis for fields."&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;Both statements are subtly incorrect.&lt;/P&gt;
&lt;P&gt;The first statement is incorrect because the compiler in fact cannot and does not prove that a local variable is not assigned. Proving that is (1) impossible, and (2) does not give us any useful information we can act upon. It's impossible because proving that a given variable is assigned a value is equivalent to solving the Halting Problem:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;int x;&lt;BR&gt;if (/*condition requiring solution of the halting problem here*/) x = 10;&lt;BR&gt;print(x);&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;If what we wanted to do was prove that x was &lt;EM&gt;unassigned&lt;/EM&gt; then we would have to &lt;EM&gt;at compile time&lt;/EM&gt; prove that the condition was false.&amp;nbsp;Our compiler is not that sophisticated! &lt;/P&gt;
&lt;P&gt;But the deeper point here is that we're not interested in proving for certain that x is &lt;EM&gt;unassigned&lt;/EM&gt;. We're interested in proving for certain that x is &lt;EM&gt;assigned&lt;/EM&gt;! If we can prove that for certain, then x is "definitely assigned". If we cannot prove that for certain then x is "not definitely assigned". We're only interested in "definitely unassigned" insofar as "definitely unassigned" is a stronger version of "not definitely assigned". If x is read from when it is "not definitely assigned", that's a bug. &lt;/P&gt;
&lt;P&gt;That is, we're attempting to prove that x is assigned, and our failure to prove that at every point where it is read is what motivates the error. That failure could be because of a bona fide bug in your program, or it could be because our flow analyzer is extremely conservative. For example:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;int x, y = 0;&lt;BR&gt;if (0 * y == 0) x = 10;&lt;BR&gt;print(x);&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;You and I know that x is definitely assigned, but in C# 3 the compiler is &lt;EM&gt;deliberately&lt;/EM&gt; not smart enough to prove that. (Interestingly enough, it &lt;EM&gt;was&lt;/EM&gt; smart&amp;nbsp;enough in C# 2. &lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2006/03/29/the-root-of-all-evil-part-two.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2006/03/29/the-root-of-all-evil-part-two.aspx"&gt;I broke that to bring the compiler into line with&amp;nbsp;the spec; being smarter but in violation of the spec is not necessarily a good thing&lt;/A&gt;.)&amp;nbsp;&lt;/P&gt;
&lt;P&gt;This example again shows that we do not prove that x is unassigned; if we did prove that, then clearly our prover would contain an error, since you and I both know that x is definitely assigned. Rather, we fail to prove that x is assigned.&lt;/P&gt;
&lt;P&gt;This is an interesting twist on&amp;nbsp;the believers vs skeptics argument that goes like this: the skeptic says "there's no reliable evidence that bigfoot exists, therefore, bigfoot does not exist". The believer says&amp;nbsp;"absence of reliable evidence is not itself evidence of absence; and yes, bigfoot&amp;nbsp;does exist". In both cases, reasoning from a position of lacking reliable evidence is seldom good reasoning! But in our case, it is precisely &lt;EM&gt;because&lt;/EM&gt; we lack reliable evidence that we are coming to the conclusion that we do not know enough to allow you to read from x.&lt;/P&gt;
&lt;P&gt;(The relevant principle for tentatively concluding that bigfoot is mythical based on a lack of reliable evidence&amp;nbsp;is "extraordinary claims require extraordinary evidence". &lt;EM&gt;It&lt;/EM&gt; &lt;EM&gt;is reasonable to assume that&amp;nbsp;an extraordinary claim is false until reliable evidence is produced&lt;/EM&gt;.&amp;nbsp;When overwhelmingly reliable evidence is produced of an extraordinary claim -- say, the extraordinary claim that&amp;nbsp;time itself slows down when you move faster -- then it makes sense to believe the extraordinary claim. Overwhelming evidence has been provided for the theory of relativity, but not for the theory of bigfoot.)&lt;/P&gt;
&lt;P&gt;The second myth is that the default constructor of a class&amp;nbsp;initializes the fields to their default values. This can be shown to be false by several arguments. &lt;/P&gt;
&lt;P&gt;First, a class need not have a default constructor, and yet its fields are always observed to be initially assigned. If there is no default constructor, then something else must be initializing the fields. &lt;/P&gt;
&lt;P&gt;Second, even if a class does have a default constructor, there's no guarantee that it will be called. Some other constructor could be called.&lt;/P&gt;
&lt;P&gt;Third, the field initializers of a class run before any constructor body runs, therefore it cannot be the constructor body that does the initialization; that would be wiping out the results of the field initializers. &lt;/P&gt;
&lt;P&gt;Fourth, constructors can call other constructors; if each of those constructors was initializing the fields to zero, then that would be wasteful; we'd be unneccessarily re-initializing already-wiped-out fields. &lt;/P&gt;
&lt;P&gt;What actually happens is that the CLI memory allocator guarantees that the memory allocated for a given class instance will be initialized to all zeros before the constructor is called. By the time the constructors run the object is already freshly zeroed out&amp;nbsp;and ready to go.&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=9905526" width="1" height="1"&gt;</content><author><name>EricLippert</name><uri>http://blogs.msdn.com/members/EricLippert.aspx</uri></author><category term="C#" scheme="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx" /><category term="Science" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Science/default.aspx" /><category term="Memory Management" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Memory+Management/default.aspx" /><category term="myths" scheme="http://blogs.msdn.com/ericlippert/archive/tags/myths/default.aspx" /><category term="relativity" scheme="http://blogs.msdn.com/ericlippert/archive/tags/relativity/default.aspx" /><category term="skepticism" scheme="http://blogs.msdn.com/ericlippert/archive/tags/skepticism/default.aspx" /><category term="definite assignment" scheme="http://blogs.msdn.com/ericlippert/archive/tags/definite+assignment/default.aspx" /><category term="constructors" scheme="http://blogs.msdn.com/ericlippert/archive/tags/constructors/default.aspx" /></entry><entry><title>What's the difference between "as" and "cast" operators?</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/ericlippert/archive/2009/10/08/what-s-the-difference-between-as-and-cast-operators.aspx" /><id>http://blogs.msdn.com/ericlippert/archive/2009/10/08/what-s-the-difference-between-as-and-cast-operators.aspx</id><published>2009-10-08T16:36:00Z</published><updated>2009-10-08T16:36:00Z</updated><content type="html">&lt;DIV class=mine&gt;
&lt;P&gt;Most people will tell you that the difference between "&lt;SPAN class=code&gt;(Alpha) bravo&lt;/SPAN&gt;" and "&lt;SPAN class=code&gt;bravo as Alpha&lt;/SPAN&gt;" is that the former throws an exception if the conversion fails, whereas the latter returns null. Though this is correct, and this is the most obvious difference, it's not the only difference. There are pitfalls to watch out for here.&lt;/P&gt;
&lt;P&gt;First off, since the result of the "as" operator can be null, the resulting type has to be one that takes a null value: either a reference type or a nullable value type. You cannot do "as int", that doesn't make any sense. If the argument isn't an int, then what should the return value be? The type of the "as" expression is always the named type so it needs to be a type that can take a null.&lt;/P&gt;
&lt;P&gt;Second, &lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2009/03/19/representation-and-identity.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2009/03/19/representation-and-identity.aspx"&gt;the cast operator, as I've discussed before, is a strange beast&lt;/A&gt;. It means two contradictory things: "check to see if this object really is of this type, throw if it is not" and "this object is not of the given type; find me an equivalent value that belongs to the given type". The latter meaning of the cast operator is not shared by the "as" operator. If you say&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;short s = (short)123;&lt;BR&gt;int? i = s as int?;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;then you're out of luck. The "as" operator will not make the representation-changing conversions from short to nullable int like the cast operator would. Similarly, if you have class Alpha and unrelated class Bravo, with a user-defined conversion from Bravo to Alpha, then "&lt;SPAN class=code&gt;(Alpha) bravo&lt;/SPAN&gt;" will run the user-defined conversion, but "&lt;SPAN class=code&gt;bravo as Alpha&lt;/SPAN&gt;" will not. The "as" operator only considers reference, boxing and unboxing conversions.&lt;/P&gt;
&lt;P&gt;And finally, of course the use cases of the two operators are superficially similar, but semantically quite different. A cast communicates to the reader "I am certain that this conversion is legal and I am willing to take a runtime exception if I'm wrong". The "as" operator communicates "I don't know if this conversion is legal or not; we're going to give it a try and see how it goes". &lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9900307" width="1" height="1"&gt;</content><author><name>EricLippert</name><uri>http://blogs.msdn.com/members/EricLippert.aspx</uri></author><category term="C#" scheme="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx" /><category term="Conversions" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Conversions/default.aspx" /><category term="What's The Difference?" scheme="http://blogs.msdn.com/ericlippert/archive/tags/What_2700_s+The+Difference_3F00_/default.aspx" /><category term="cast operator" scheme="http://blogs.msdn.com/ericlippert/archive/tags/cast+operator/default.aspx" /></entry><entry><title>Why No Extension Properties?</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/ericlippert/archive/2009/10/05/why-no-extension-properties.aspx" /><id>http://blogs.msdn.com/ericlippert/archive/2009/10/05/why-no-extension-properties.aspx</id><published>2009-10-05T16:29:00Z</published><updated>2009-10-05T16:29:00Z</updated><content type="html">&lt;DIV class=mine&gt;
&lt;P&gt;I'm frequently asked "you guys added extension methods to C# 3, so why not add extension properties as well?"&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Good question.&lt;/P&gt;
&lt;P&gt;First, let me talk a bit about C# 3. Clearly the big feature in C# 3 was LINQ. In a sense we had only three features in C# 3:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;everything necessary for LINQ -- implicitly typed locals, anonymous types, lambda expressions, extension methods, object and collection initializers, query comprehensions, expression trees, improved method type inference&lt;/LI&gt;
&lt;LI&gt;partial methods&lt;/LI&gt;
&lt;LI&gt;automatically implemented&amp;nbsp;properties&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;The latter two were&amp;nbsp;tiny compared to the&amp;nbsp;items in that&amp;nbsp;first bucket. On the design side, the syntax and semantics of both features are straightforward. On the implementation side, we already had the mechanisms in place to remove a call site; partial methods and conditional methods are pretty much the same thing behind the scenes. Auto props were also straightforward to analyze and generate code for. The testing burden was not particularly&amp;nbsp;large for these features either.&lt;/P&gt;
&lt;P&gt;The C# team was "the long pole" for the 2008 release of Visual Studio and the .NET Framework. By that I mean that if you took the amount of time required to do the work&amp;nbsp;each team signed up for, given our level of staffing, blah blah blah, and made a pole proportionally long for each team in Developer Division, the C# pole would have been the longest pole. Which means that every other team in devdiv had slack in their schedule, but&amp;nbsp;if we slipped our schedule a day,&amp;nbsp;the new VS/CLR&amp;nbsp;would also ship a day late. If any other team slipped a day, well, as long as that didn't make their pole longer than ours, they were still OK. Within the team, dividing up the work amongs the various development team members, the "long pole" work was the lambda binding and method type inference work, which was mine. So in a sense, every day that I was late, we'd slip the whole product that many days. (No pressure!)&lt;/P&gt;
&lt;P&gt;Fortunately we have an excellent team here, we all supported each other very well through that release, picked up each other's slack when necessary, and delivered a quality release in plenty of time. My point is&amp;nbsp;simply that &lt;STRONG&gt;unless a feature was either necessary for LINQ, or small and orthogonal and easy to cut if necessary (like the other two), it got cut immediately&lt;/STRONG&gt;. There was no way we were going to risk slipping the entire product for any feature that was both &lt;EM&gt;complex&lt;/EM&gt; and &lt;EM&gt;unnecessary&lt;/EM&gt;.&lt;/P&gt;
&lt;P&gt;It was of course immediately obvious that the natural companion to extension methods is extension properties. It's less obvious, for some reason, that extension events, extension operators, extension constructors (also known as "the factory pattern"), and so on, are also natural companions. But we didn't even &lt;EM&gt;consider&lt;/EM&gt; designing extension properties for C# 3; we knew that they were not necessary and would add risk to an already-risky schedule for no compelling gain. &lt;/P&gt;
&lt;P&gt;So now we come to C# 4. &lt;/P&gt;
&lt;P&gt;As I'm fond of pointing out, the answer to every question of the form "why doesn't product X have&amp;nbsp;feature Y?" is the same.&amp;nbsp;It's because in order for a product to have a feature, that feature must be:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;thought of in the first place&lt;/LI&gt;
&lt;LI&gt;desired&lt;/LI&gt;
&lt;LI&gt;designed&amp;nbsp;&lt;/LI&gt;
&lt;LI&gt;specified&lt;/LI&gt;
&lt;LI&gt;implemented&lt;/LI&gt;
&lt;LI&gt;tested&lt;/LI&gt;
&lt;LI&gt;documented&lt;/LI&gt;
&lt;LI&gt;shipped to customers&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;You've got to hit every single one of those things,&amp;nbsp;otherwise, no feature.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;When we started working on C# 4, we made a list of every feature request we'd heard of. It had hundreds of features on it. &lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2008/10/08/the-future-of-c-part-one.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2008/10/08/the-future-of-c-part-one.aspx"&gt;As I described last year&lt;/A&gt;, we categorized that list into "gotta have / nice to have / bad idea" buckets. Extension properties were in the "gotta have" bucket. We then looked at our available budget -- which was not so much measured in dollars as in available designers, developers, testers, writers and management multiplied by available time -- and determined that we did not have the resources to do more than about half the things in the "gotta have" bucket. So we cut half that stuff. Extension properties made it past that cut.&lt;/P&gt;
&lt;P&gt;We then designed the feature. We had many hours of debate about the proposed syntax on the declaration side, how to call an extension property getter or setter "directly" as a static method, and so on. We came up with a syntax we could agree was acceptable, designed the semantics, wrote up a draft specification, and started writing code and test plans.&lt;/P&gt;
&lt;P&gt;By the time the code was in reasonable shape -- not yet seriously tested, but usable and compliant with the spec -- we'd been having meetings with the WPF team. WPF developers&amp;nbsp;were the assumptive primary consumers of extension properties. WPF&amp;nbsp;already has a mechanism that resembles extension properties; it would be nice to unify that mechanism with our mechanism. Unfortunately, after taking a deep look at their real-world scenarios, we came to the disappointing conclusion that we had designed the wrong thing; this was not actually a feature that would solve their problems.&lt;/P&gt;
&lt;P&gt;This is, admittedly, in a sense a failure of the design process. In retrospect, we should have gotten input and feedback from the primary customer much earlier. Had we done that then they could have either influenced the design to make something that would work for them, or we could have cut the feature without taking on the expense of writing spec, code and test plans. &lt;/P&gt;
&lt;P&gt;But when you're in an unfortunate situation, you've got to decide to stop throwing good money after bad. Rather than take on the additional costs -- testing, documentation, shipping, and then maintenance of the feature for the rest of the life of the language -- in exchange for a feature that did not serve the needs of our customers, we cut the feature. At that point we did not feel confident that we had enough cycles remaining to redesign the feature the right way.&lt;/P&gt;
&lt;P&gt;Therefore, sadly, no extension properties in C# 4. Perhaps in a hypothetical future version of C#.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9899167" width="1" height="1"&gt;</content><author><name>EricLippert</name><uri>http://blogs.msdn.com/members/EricLippert.aspx</uri></author><category term="C#" scheme="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx" /><category term="C# 4.0" scheme="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_+4.0/default.aspx" /><category term="Language Design" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Language+Design/default.aspx" /><category term="extension properties" scheme="http://blogs.msdn.com/ericlippert/archive/tags/extension+properties/default.aspx" /></entry><entry><title>Why does char convert implicitly to ushort but not vice versa?</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/ericlippert/archive/2009/10/01/why-does-char-convert-implicitly-to-ushort-but-not-vice-versa.aspx" /><id>http://blogs.msdn.com/ericlippert/archive/2009/10/01/why-does-char-convert-implicitly-to-ushort-but-not-vice-versa.aspx</id><published>2009-10-01T19:53:00Z</published><updated>2009-10-01T19:53:00Z</updated><content type="html">&lt;DIV class=mine&gt;
&lt;P&gt;&lt;A href="http://stackoverflow.com/questions/1503430/implicit-type-cast-in-c/1504959#1504959" mce_href="http://stackoverflow.com/questions/1503430/implicit-type-cast-in-c/1504959#1504959"&gt;Another good question from StackOverflow&lt;/A&gt;. Why is there an implicit conversion from char to ushort, but only an explicit conversion from ushort to char? Why did the designers of the language believe that these asymmetrical rules were sensible rules to add to the language?&lt;/P&gt;
&lt;P&gt;Well, first off, the obvious things which would &lt;EM&gt;prevent&lt;/EM&gt; either conversion from being implicit do not apply. A char is implemented as an unsigned 16 bit integer that represents a character in a UTF-16 encoding, so it can be converted to or from a ushort without loss of precision, or, for that matter, without change of representation. The runtime simply goes from treating this bit pattern as a char to treating the same bit pattern as a ushort, or vice versa.&lt;/P&gt;
&lt;P&gt;It is therefore &lt;EM&gt;possible&lt;/EM&gt; to allow either implicit conversion. Now, just because something is possible does not mean it is a good idea. Clearly the designers of the language thought that implicitly converting char to ushort was a good idea, but implicitly converting ushort to char is not. (And since char to ushort is a good idea, it seems reasonable that char-to-anything-that-ushort-goes-to is also reasonable, hence, char to int is also good.)&lt;/P&gt;
&lt;P&gt;Unlike you guys, I have the original notes from the language design team at my disposal. Digging through those, we discover some interesting facts.&lt;/P&gt;
&lt;P&gt;The conversion from ushort to char is covered in the notes from April 14th, 1999, where the question of whether it should be legal to convert from byte to char arises. &lt;STRONG&gt;In the original pre-release version of C#, this was legal for a brief time.&lt;/STRONG&gt; I've lightly edited the notes to make them clear without an understanding of 1999-era pre-release Microsoft code names. I've also added emphasis on important points:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;[The language design committee] has chosen to provide an implicit conversion from bytes to chars, since the domain of one is completely contained by the other. Right now, however, [the runtime library authors] only provide Write methods which take chars and ints, which means that bytes print out as characters since that ends up being the best method. We can solve this either by providing more methods on the writer class or by removing the implicit conversion. &lt;/P&gt;
&lt;P&gt;There is an argument for why the latter is the correct thing to do. After all, &lt;STRONG&gt;bytes really aren't characters&lt;/STRONG&gt;. True, there may be a &lt;EM&gt;useful mapping&lt;/EM&gt; from bytes to chars, but ultimately, &lt;STRONG&gt;23 does not denote the same thing as the character with ASCII value 23, in the same way that the byte 23 denotes the same thing as the long 23&lt;/STRONG&gt;. Asking [the library authors] to provide this additional method simply because of how a quirk in our type system works out seems rather weak.&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;The notes then conclude with the decision that byte-to-char should be an explicit conversion, and integer-literal-in-range-of-char should also be an explicit conversion.&lt;/P&gt;
&lt;P&gt;Note that the language design notes do not call out why ushort-to-char was also made explicit at the same time, but you can see that the same logic applies. When passing a ushort to a method overloaded as M(int) and M(char), odds are good that you want to treat the ushort as a number, not as a character. And a ushort is not a character representation in the same way that a ushort is a numeric representation, so it seems reasonable to make that conversion explicit as well.&lt;/P&gt;
&lt;P&gt;The decision to make char go to ushort implicitly was made on the 17th of September, 1999; the design notes from that day on this topic simply state "char to ushort is also a legal implicit conversion", and that's it. No further exposition of what was going on in the language designers' heads that day is evident in the notes. &lt;/P&gt;
&lt;P&gt;However, we can make &lt;EM&gt;educated guesses&lt;/EM&gt; as to why implicit char-to-ushort was considered a good idea. The key idea here is that the conversion from number to character is a "possibly dodgy" conversion. It's taking something that you do not know is intended to be a character, and choosing to treat it as one. That seems like the sort of thing you want to call out that you are doing explicitly, rather than accidentally allowing it. But the reverse is much less dodgy. There is a long tradition in C programming of treating characters as integers -- to obtain their underlying values, or to do mathematics on them. &lt;/P&gt;
&lt;P&gt;In short: it seems reasonable that using a number as a character could be an accident and a bug, but it also seems reasonable that using a character as a number is deliberate and desirable. This asymmetry is therefore reflected in the rules of the language.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9901940" width="1" height="1"&gt;</content><author><name>EricLippert</name><uri>http://blogs.msdn.com/members/EricLippert.aspx</uri></author><category term="C#" scheme="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx" /><category term="Conversions" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Conversions/default.aspx" /><category term="integer arithmetic" scheme="http://blogs.msdn.com/ericlippert/archive/tags/integer+arithmetic/default.aspx" /></entry><entry><title>String interning and String.Empty</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/ericlippert/archive/2009/09/28/string-interning-and-string-empty.aspx" /><id>http://blogs.msdn.com/ericlippert/archive/2009/09/28/string-interning-and-string-empty.aspx</id><published>2009-09-28T16:23:00Z</published><updated>2009-09-28T16:23:00Z</updated><content type="html">&lt;DIV class=mine&gt;
&lt;P&gt;Here's a curious program fragment:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;object obj = "Int32";&lt;BR&gt;string str1 = "Int32";&lt;BR&gt;string str2 = typeof(int).Name;&lt;BR&gt;Console.WriteLine(obj == str1); // true&lt;BR&gt;Console.WriteLine(str1 == str2); // true&lt;BR&gt;Console.WriteLine(obj == str2); // false !?&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Surely if A equals B, and B equals C, then A equals C; that's the &lt;EM&gt;transitive property&lt;/EM&gt; of equality. It appears to have been thoroughly violated here.&lt;/P&gt;
&lt;P&gt;Well, first off, though the transitive property is desirable, this is just one of many situations in which equality is intransitive in C#. You shouldn't rely upon transitivity &lt;EM&gt;in general&lt;/EM&gt;, though of course there are many specific cases where it is valid. As an exercise, you might want to see how many other intransitivities you can come up with. Post 'em in the comments; I'd love to see what obscure ones you can come up with. (Incidentally, one of the interview questions I got when applying for this team was to invent&amp;nbsp;a performant&amp;nbsp;algorithm for determining intransitivities in a simplified version of the 'better method' algorithm.)&lt;/P&gt;
&lt;P&gt;Second, what's happening here is we're mixing two different kinds of equality that just happen to use the same operator syntax. We're mixing &lt;EM&gt;reference&lt;/EM&gt; equality with &lt;EM&gt;value&lt;/EM&gt; equality. Objects are compared by reference; in the first and third comparison we are testing if the two object references both refer to exactly the same object. In the second comparison we are checking to see if the two strings have the same content, regardless of whether they are the same object or not. In fact, the compiler warns you about this situation; this should produce a "possible unintended reference comparison" warning.&lt;/P&gt;
&lt;P&gt;That might need a bit more explanation. &lt;EM&gt;In .NET you can have two strings that have identical content but are different objects&lt;/EM&gt;. When you compare those strings &lt;EM&gt;as strings&lt;/EM&gt;, they're equal, but when you compare them &lt;EM&gt;as objects&lt;/EM&gt;, they're not.&lt;/P&gt;
&lt;P&gt;That explains why the second comparison is true -- it's a value comparison -- and why the third comparison is false -- it's a reference comparison. But it doesn't explain why the first and third comparisons are inconsistent with each other.&lt;/P&gt;
&lt;P&gt;This is the result of a small optimization. If you have two identical string literals in one compilation unit then&amp;nbsp;the code we generate ensures that &lt;EM&gt;only one string object is created by the CLR for all instances of that literal within the assembly&lt;/EM&gt;. This optimization is called "string interning".&lt;/P&gt;
&lt;P&gt;String.Empty is not a constant, it's a read-only field in another assembly. Therefore it is not interned with the empty string in your assembly; those are two different objects. &lt;/P&gt;
&lt;P&gt;This explains why the first comparison is true: the two literals in fact get turned into the same string object. And it explains why the third comparison is false: the literal and&amp;nbsp;the computed value&amp;nbsp;are turned into different objects.&lt;/P&gt;
&lt;P&gt;Knowing that, you can now make an educated guess as to why we have this bizarre behaviour:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;object obj = "";&lt;BR&gt;string str1 = "";&lt;BR&gt;string str2 = String.Empty;&lt;BR&gt;Console.WriteLine(obj == str1); // true&lt;BR&gt;Console.WriteLine(str1 == str2); // true&lt;BR&gt;Console.WriteLine(obj == str2); // sometimes true, sometimes false?!&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Some versions of the .NET runtime automatically intern the empty string at runtime, some do not!&lt;/P&gt;
&lt;P&gt;But why, you might ask, do we not perform this interning optimization &lt;EM&gt;at runtime&lt;/EM&gt; on &lt;EM&gt;every string&lt;/EM&gt;? Why not aggressively turn all value-equal strings into reference-equal strings?&amp;nbsp;Surely it is wasteful to have two identical strings around when you could have half as much memory.&lt;/P&gt;
&lt;P&gt;The answer is that the&amp;nbsp;&lt;A class="" href="http://en.wikipedia.org/wiki/TANSTAAFL" mce_href="http://en.wikipedia.org/wiki/TANSTAAFL"&gt;TANSTAAFL&lt;/A&gt; Principle applies here, bigtime. That is, &lt;STRONG&gt;There Ain't No Such Thing As A Free Lunch&lt;/STRONG&gt;. Interning has two positive effects: it decreases memory consumption and decreases time required to compare two strings. (Because if all strings are interned at runtime then &lt;EM&gt;all&lt;/EM&gt; string comparisons can be cheap reference comparisons.) But those positive effects have a cost: allocating a new string now requires that you do a search of all string objects in memory to see if you have one that matches already. In our existing optimization, the cost is small; we can know at compile time what string literals are in a given assembly and which are identical. With the proposed optimization, that cost is imposed at runtime, and it could be a very large fraction of the time spent allocating strings. &lt;/P&gt;
&lt;P&gt;In order to keep the time cost down, you'd have to build&amp;nbsp;a hash table of all strings in memory. That means&amp;nbsp;either computing the hashes frequently, which is&amp;nbsp;itself&amp;nbsp;expensive in time, or storing the hashes somewhere. If we do the latter then suddenly we are &lt;EM&gt;increasing&lt;/EM&gt; the memory burden for strings that are &lt;EM&gt;not duplicated&lt;/EM&gt;. That is, our optimization makes the normal scenario --&amp;nbsp;the vast majority of pairs of&amp;nbsp;strings are not equal to each other -- take up more memory, so that a rare scenario saves on memory. That seems like a bad bargain; you usually want to optimize for the likely case.&lt;/P&gt;
&lt;P&gt;There are also serious lifetime problems with interned strings. When can they be safely garbage collected? What if a new copy of the string is created while the old one is being collected on another thread? The safest thing to do is to make interned strings immortal, which looks like a memory leak. Memory leaks are bad for performance, particularly when the optimization you're doing is an attempt to &lt;EM&gt;save memory&lt;/EM&gt;. TANSTAAFL!&lt;/P&gt;
&lt;P&gt;In short, it is in the general case not worth it to intern all strings. &lt;EM&gt;However, it might be worth it in some specific cases.&lt;/EM&gt; For example, if you were building a compiler in C#, odds are good that you are going to be&amp;nbsp;producing a lot of strings that are the same at runtime. Our C# compiler is written in C++,&amp;nbsp;in which&amp;nbsp;we have written our own custom string interning layer so that we can do cheap reference comparisons on all strings in your program. Odds are good that "int" is going to appear tens, hundreds or thousands of times in a given program; it seems silly to allocate the same string over and over again. If you were writing a compiler in C#, or had some other application in which you felt that it was worth your while to ensure that thousands of identical strings do not consume lots of memory, you can force the runtime to intern your string with the &lt;A class="" href="http://msdn.microsoft.com/en-us/library/system.string.intern.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.string.intern.aspx"&gt;String.Intern&lt;/A&gt; method.&lt;/P&gt;
&lt;P&gt;Conversely, if you hate interning with an unreasoning passion, you can force the runtime to turn off all string interning in an assembly with the &lt;A class="" href="http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.compilationrelaxationsattribute.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.compilationrelaxationsattribute.aspx"&gt;CompilationRelaxation&lt;/A&gt; attribute.&lt;/P&gt;
&lt;P&gt;Anyway, to come back to the question of transitivity: object reference equality&amp;nbsp;actually is transitive. It's also symmetric (A==B implies B==A) and reflexive (A==A), so it is an equivalence relation. Similarly, string value equality is transitive, symmetric and reflexive, since it uses a straight "character by character" ordinal comparison. But when you &lt;EM&gt;mix &lt;/EM&gt;the two, then equality is no longer transitive. That's weird, but hopefully now understandable.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9897605" width="1" height="1"&gt;</content><author><name>EricLippert</name><uri>http://blogs.msdn.com/members/EricLippert.aspx</uri></author><category term="Performance" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Performance/default.aspx" /><category term="C#" scheme="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx" /><category term="equality" scheme="http://blogs.msdn.com/ericlippert/archive/tags/equality/default.aspx" /><category term="string interning" scheme="http://blogs.msdn.com/ericlippert/archive/tags/string+interning/default.aspx" /></entry><entry><title>Why is covariance of value-typed arrays inconsistent?</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/ericlippert/archive/2009/09/24/why-is-covariance-of-value-typed-arrays-inconsistent.aspx" /><id>http://blogs.msdn.com/ericlippert/archive/2009/09/24/why-is-covariance-of-value-typed-arrays-inconsistent.aspx</id><published>2009-09-24T16:53:00Z</published><updated>2009-09-24T16:53:00Z</updated><content type="html">&lt;DIV class=mine&gt;
&lt;P&gt;Another&amp;nbsp;interesting &lt;A class="" href="http://stackoverflow.com/questions/1178973/why-does-my-c-array-lose-type-sign-information-when-cast-to-object/1179094#1179094" mce_href="http://stackoverflow.com/questions/1178973/why-does-my-c-array-lose-type-sign-information-when-cast-to-object/1179094#1179094"&gt;question from StackOverflow&lt;/A&gt;:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;uint[] foo = new uint[10];&lt;BR&gt;object bar = foo;&lt;BR&gt;Console.WriteLine("{0} {1} {2} {3}",&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp; foo is uint[],&amp;nbsp;// True&lt;BR&gt;&amp;nbsp; foo is int[],&amp;nbsp;&amp;nbsp;// False&lt;BR&gt;&amp;nbsp; bar is uint[],&amp;nbsp;// True&lt;BR&gt;&amp;nbsp; bar is int[]);&amp;nbsp;// True&lt;BR&gt;&lt;BR&gt;&lt;/SPAN&gt;What the heck is going on here?&lt;/P&gt;
&lt;P&gt;This program fragment illustrates an interesting and unfortunate inconsistency between the CLI type system and the C# type system.&lt;/P&gt;
&lt;P&gt;The CLI has the concept of "assignment compatibility". If a value x of known data type S is "assignment compatible" with a particular storage location y of known data type T, then you can store x in y. If not, then doing so is not verifiable code and the verifier will disallow it.&lt;/P&gt;
&lt;P&gt;The CLI type system says, for instance, that subtypes of reference type are assignment compatible with supertypes of reference type. If you have a string, you can store it in a variable of type object, because both are reference types and string is a subtype of object. But the opposite is not true; supertypes are not assignment compatible with subtypes. You can't stick something only known to be object into a variable of type string without first casting it.&lt;/P&gt;
&lt;P&gt;Basically "assignment compatible" means "&lt;EM&gt;it makes sense to stick these exact bits into this variable&lt;/EM&gt;". The assignment from source value to target variable has to be "&lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2009/03/19/representation-and-identity.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2009/03/19/representation-and-identity.aspx"&gt;representation preserving&lt;/A&gt;". &lt;A href="http://blogs.msdn.com/ericlippert/archive/2009/03/19/representation-and-identity.aspx"&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;One of the rules of the CLI is "&lt;EM&gt;if X is assignment compatible with Y then X[] is assignment compatible with Y[]&lt;/EM&gt;". &lt;/P&gt;
&lt;P&gt;That is, arrays are covariant with respect to assignment compatibility. As I've discussed already, &lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2007/10/17/covariance-and-contravariance-in-c-part-two-array-covariance.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2007/10/17/covariance-and-contravariance-in-c-part-two-array-covariance.aspx"&gt;this is actually a broken kind of covariance&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;That is &lt;EM&gt;not&lt;/EM&gt; a rule of C#. C#'s array covariance rule is "&lt;EM&gt;if X is a &lt;STRONG&gt;reference type&lt;/STRONG&gt; implicitly convertible to &lt;STRONG&gt;reference type&lt;/STRONG&gt; Y then X[] is implicitly convertible to Y[]&lt;/EM&gt;". That is a subtly different rule!&lt;/P&gt;
&lt;P&gt;In the CLI, uint and int are assignment compatible; therefore uint[] and int[] are too. But in C#, the conversion between int and uint is &lt;EM&gt;explicit&lt;/EM&gt;, not &lt;EM&gt;implicit&lt;/EM&gt;, and these are &lt;EM&gt;value types&lt;/EM&gt;, not &lt;EM&gt;reference types&lt;/EM&gt;. So in C# it is &lt;EM&gt;not&lt;/EM&gt; legal to convert an int[] to a uint[]. But it &lt;EM&gt;is&lt;/EM&gt; legal in the CLI. So now we are faced with a choice.&lt;/P&gt;
&lt;P&gt;1) Implement "is" so that when the compiler cannot determine the answer statically, it actually calls a method which checks all the C# rules for identity-preserving convertibility. This is slow, and 99.9% of the time matches what the CLR rules are. But we take the performance hit so as to be 100% compliant with the rules of C#.&lt;/P&gt;
&lt;P&gt;2) Implement "is" so that when the compiler cannot determine the answer statically, it does the incredibly fast CLR assignment compatibility check, and live with the fact that this says that a uint[] is an int[], even though that would not actually be legal in C#.&lt;/P&gt;
&lt;P&gt;We chose the latter. It is unfortunate that C# and the CLI specifications disagree on this minor point but we are willing to live with the inconsistency.&lt;/P&gt;
&lt;P&gt;So what's going on here is that in the "foo" cases, the compiler can determine statically what the answer is going to be according to the rules of C#, and generates code to produce "True" and "False". But in the "bar" case, the compiler no longer knows what exact type is in bar, so it generates code to make the CLR answer the question, and the CLR gives a different opinion.&lt;BR&gt;&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=9895929" width="1" height="1"&gt;</content><author><name>EricLippert</name><uri>http://blogs.msdn.com/members/EricLippert.aspx</uri></author><category term="C#" scheme="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx" /><category term="Covariance and Contravariance" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/default.aspx" /><category term="Arrays" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Arrays/default.aspx" /></entry></feed>