<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Fabulous Adventures In Coding : C#</title><link>http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx</link><description>Tags: C#</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Query transformations are syntactic</title><link>http://blogs.msdn.com/ericlippert/archive/2009/12/07/query-transformations-are-syntactic.aspx</link><pubDate>Mon, 07 Dec 2009 14:20:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9931506</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>11</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9931506.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9931506</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;As you probably know, there are two ways to write a LINQ query in C#. The way I personally prefer is to use the “query comprehension” syntax:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;from customer in customerList&lt;BR&gt;where customer.City == "London" &lt;BR&gt;select customer.Name&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Or you can, equivalently, use the “fluent method call” syntax:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;customerList&lt;BR&gt;.Where(customer=&amp;gt;customer.City == "London")&lt;BR&gt;.Select(customer=&amp;gt;customer.Name)&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;These are guaranteed to be equivalent because &lt;STRONG&gt;the compiler simply transforms the former syntax into the latter syntax before it compiles it&lt;/STRONG&gt;. An interesting aspect of this transformation is that it is (almost) entirely &lt;STRONG&gt;syntactic&lt;/STRONG&gt;. (The "transparent identifiers"&amp;nbsp;generated for certain queries require a small amount of semantic analysis to determine the corresponding anonymous type,&amp;nbsp;but for the most part, all we do is just pull the raw hunks of code out of each clause and reorganize the program into the method call form.) Once it is in a form that the rest of the compiler can understand, then semantic analysis proceeds as usual.&lt;/P&gt;
&lt;P&gt;This means that it is perfectly legal to do dumb things. For example, suppose we decide that by “where” we mean don’t mean “filter”, we actually mean “multiply”. And by “select” we actually mean “add”, not “project”. No problem!&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;static class ExtInt&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static&amp;nbsp;int Where(this int c, Func&amp;lt;int, int&amp;gt; f)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return f(0) * c;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static&amp;nbsp;int Select(this int c, Func&amp;lt;int, int&amp;gt; f)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return f(0) + c;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;}&lt;BR&gt;…&lt;BR&gt;int ten = 10;&lt;BR&gt;int&amp;nbsp;twenty = 20;&lt;BR&gt;int&amp;nbsp;thirty = 30;&amp;nbsp;&lt;BR&gt;int result = from c in ten where twenty select thirty; &lt;BR&gt;Console.WriteLine(result); &lt;/SPAN&gt;
&lt;P&gt;And sure enough, ten where/times&amp;nbsp;twenty select/plus thirty is 230. This is a deeply strange way to write a mathematical expression, but legal. 
&lt;P&gt;The semantics of the Where method are supposed to be “takes a collection of T and a predicate mapping T to bool, and returns a filtered collection of those T items which match the predicate”. This method does not take a collection or a predicate, it does not return a collection, and it certainly does not have the semantics of filtering, but the compiler neither knows nor cares about any of those facts. All the compiler does is syntactically turn that line into &lt;SPAN class=code&gt;
&lt;P&gt;int&amp;nbsp;result = ten.Where(c=&amp;gt;twenty).Select(c=&amp;gt;thirty);&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;and compile it; &lt;EM&gt;that&lt;/EM&gt; line compiles just fine, so, no problem as far as the compiler is concerned. 
&lt;P&gt;The C# specification has a section which describes the pattern we expect a query provider to implement: that Where takes a predicate, and so on. But we perform no checks whatsoever that you successfully implemented a query provider that implements either the form or the semantics of our recommended pattern. If you do something crazy, like redefine “where” to take something other than a predicate and you get crazy results, then, well, what can I tell you? If it hurts when you do that then don’t do that! 
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9931506" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/queries/default.aspx">queries</category></item><item><title>Exact rules for variance validity</title><link>http://blogs.msdn.com/ericlippert/archive/2009/12/03/exact-rules-for-variance-validity.aspx</link><pubDate>Thu, 03 Dec 2009 14:32:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9923708</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>15</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9923708.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9923708</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;I thought it might be interesting for you all to get a precise description of how exactly it is that we determine when it is legal to put "in" and "out" on a type parameter declaration in C# 4. I'm doing this here because (1) it's of general interest, and (2) our attempt to make a more human-readable version of this algorithm in the draft C# 4.0 specification accidentally introduced some subtle errors. We're working on correcting those errors for the final release of the specification; until then, &lt;EM&gt;these definitions are the definitions I actually worked from to do the implementation&lt;/EM&gt;, so they're accurate. &lt;/P&gt;
&lt;P&gt;These definitions are pretty much stolen straight from the CLI spec section on variance; I am indebted to its authors for their careful and precise definitions.&lt;/P&gt;
&lt;P&gt;The first things we need to define are three kinds of "validity" for &lt;STRONG&gt;types&lt;/STRONG&gt;. I want to define "valid covariantly", "valid contravariantly" and "valid invariantly", but only as applied to &lt;STRONG&gt;types&lt;/STRONG&gt;. We'll talk about what makes an interface &lt;STRONG&gt;declaration&lt;/STRONG&gt; a valid one later; we need these definitions first.&lt;/P&gt;
&lt;P&gt;Before we get into a precise definition, I want to talk about what "valid covariantly" means logically. The idea that we are attempting to capture here boils down to "the type we're talking about is &lt;EM&gt;not contravariant&lt;/EM&gt;". Whether it is &lt;EM&gt;covariant&lt;/EM&gt;, we don't really care. All we care about it is that &lt;STRONG&gt;if it is valid covariantly, then it is not contravariant&lt;/STRONG&gt;. Similarly, by "valid contravariantly", we mean "not covariant".&lt;/P&gt;
&lt;P&gt;This leads us to our first brain-hurting definition: A type is "&lt;STRONG&gt;valid invariantly&lt;/STRONG&gt;"&amp;nbsp;if it is &lt;STRONG&gt;both&lt;/STRONG&gt; valid covariantly and valid contravariantly. That sounds a bit crazy -- how can it be valid invariantly if it is both covariant and contravariant? But "valid covariantly" does not mean "is covariant", it means "it's guaranteed to not be contravariant".&amp;nbsp;So if a type is valid covariantly and valid contravariantly, then it is guaranteed to be neither contravariant nor covariant, and therefore must be invariant.&lt;/P&gt;
&lt;P&gt;Anyway. We want to take any specific type and classify it as valid covariantly, valid contravariantly, or both, a.k.a., valid invariantly. (We don't need to worry about coming up with a term for the "or none of the above" case because in practice that case is never relevant.)&lt;/P&gt;
&lt;P&gt;A type is &lt;STRONG&gt;valid covariantly&lt;/STRONG&gt; if it is:&lt;/P&gt;
&lt;P&gt;1) a class, struct, nullable, enum, pointer, non-generic delegate or non-generic interface type.&lt;/P&gt;
&lt;P&gt;This should make sense. Remember, what we're getting at is "not contravariant". Classes and structs are either non-generic, in which case they are clearly not contravariant, or they are generic, in which case again they are not contravariant because we do not support variance on classes or structs.&amp;nbsp;Nullable types are just aliases for Nullable&amp;lt;T&amp;gt; which is a struct type, and therefore not variant. Enums&amp;nbsp;and pointers are non-generic so they are not variant. And non-generic delegates and interfaces are by definition not generic and therefore not variant either.&amp;nbsp;These&amp;nbsp;are the easy cases.&lt;/P&gt;
&lt;P&gt;2) An array type T[] where T is valid covariantly.&lt;/P&gt;
&lt;P&gt;Because we have array covariance in C#, but not array contravariance, we can make arrays valid covariantly. Again, remember, "valid covariantly" means "not contravariant".&lt;/P&gt;
&lt;P&gt;3) A generic type parameter type, if it was not declared as being contravariant.&lt;/P&gt;
&lt;P&gt;Generic type parameter types are of course types as far as the compiler is concerned. If you're inside the declaration of a generic interface then you can use its type parameters as types. In that context, such types are valid covariantly if they were not declared as contravariant (in).&lt;/P&gt;
&lt;P&gt;4) A constructed interface or delegate type X&amp;lt;T1, ... Tk&amp;gt; might be valid covariantly. To determine if it is, we examine each type argument differently, depending on whether the corresponding type parameter was declared as covariant (out), contravariant (in), or invariant (neither). If the ith&amp;nbsp;type parameter was declared as covariant, then Ti must be valid covariantly. If it was declared as contravariant, then Ti must be valid contravariantly. If it was declared as invariant, then Ti must be valid invariantly. &lt;/P&gt;
&lt;P&gt;As one would expect, covariant validity preserves the direction of validity; covariant parameters must be valid covariantly, contravariant parameters must be valid contravariantly.&lt;/P&gt;
&lt;P&gt;OK, I hope that was relatively painless. The rules for contravariant validity are similar; as one would expect from the "backwards" nature of contravariance, the directions are reversed in the complicated case:&lt;/P&gt;
&lt;P&gt;A type is &lt;STRONG&gt;valid contravariantly&lt;/STRONG&gt; if it is:&lt;/P&gt;
&lt;P&gt;1) a class, struct, nullable, enum, pointer, non-generic delegate or non-generic interface type.&lt;/P&gt;
&lt;P&gt;2) An array type T[] where T is valid contravariantly.&lt;/P&gt;
&lt;P&gt;Arrays are covariant in their element type. Covariance preserves the direction of variance. Therefore, to be valid contravariantly, an array (covariant in its element type) must be contravariantly valid in its element type.&lt;/P&gt;
&lt;P&gt;3) A generic type parameter type, if it was not declared as being covariant.&lt;/P&gt;
&lt;P&gt;Remember, "valid contravariantly" means "not covariant". It does not mean "contravariant".&lt;/P&gt;
&lt;P&gt;4) A constructed interface or delegate type X&amp;lt;T1, ... Tk&amp;gt; might be valid contravariantly. If the ith&amp;nbsp;type parameter was declared as contravariant, then Ti must be valid covariantly. If it was declared as covariant, then Ti must be valid contravariantly. If it was declared as invariant, then Ti must be valid invariantly. &lt;/P&gt;
&lt;P&gt;As one might expect, contravariant validity &lt;EM&gt;reverses&lt;/EM&gt; the direction of validity. &lt;/P&gt;
&lt;P&gt;Now perhaps you see why we wanted to rewrite these definitions into something more human-readable for the spec. And perhaps you also see why we accidentally introduced errors in doing so; bending your brain around all this logic is not always easy.&lt;/P&gt;
&lt;P&gt;OK, now that we've got that, we can make a definition of what it means for an interface to be valid. An interface must meet the following conditions:&lt;/P&gt;
&lt;P&gt;* The return types of&amp;nbsp;all non-void interface methods must be valid covariantly.&lt;/P&gt;
&lt;P&gt;* Every formal parameter type of&amp;nbsp;all interface methods must be valid contravariantly. (Invariantly if it is an out or ref parameter.)&lt;/P&gt;
&lt;P&gt;* For all generic methods on an interface,&amp;nbsp;every constraint on the generic method type parameters must be valid contravariantly.&lt;/P&gt;
&lt;P&gt;* All its base interface types&amp;nbsp;must be&amp;nbsp;valid covariantly.&lt;/P&gt;
&lt;P&gt;* The type of a property or indexer must be valid covariantly if it has a "getter" and valid contravariantly if it has a "setter".&lt;/P&gt;
&lt;P&gt;* Any formal parameter types of an indexer must be valid contravariantly.&lt;/P&gt;
&lt;P&gt;* The delegate types of all its events must be valid contravariantly.&lt;/P&gt;
&lt;P&gt;The first two are pretty straightforward; return types "go out" so they have to be valid covariantly, formal parameter types "go in", so they have to be valid contravariantly. But what's up with the third one? What do constraints on generic method type parameters have to do with interface validity?&lt;/P&gt;
&lt;P&gt;Well, let's suspend&amp;nbsp;the third rule&amp;nbsp;and see what goes wrong.&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;interface I&amp;lt;out T&amp;gt;&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; void M&amp;lt;U&amp;gt;() where U : T; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // illegal; this has to be valid contravariantly but it is a covariant type parameter constraint.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Let it ride for now and demonstrate an error.&lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;class C&amp;lt;T&amp;gt; : I&amp;lt;T&amp;gt; { public void M&amp;lt;U&amp;gt;() {} }&lt;BR&gt;// the constraint is inherited implicitly and not re-stated.&lt;/P&gt;
&lt;P&gt;I&amp;lt;Giraffe&amp;gt; igiraffe = new C&amp;lt;Giraffe&amp;gt;();&amp;nbsp;// C&amp;lt;T&amp;gt; implements I&amp;lt;T&amp;gt;&lt;BR&gt;I&amp;lt;Animal&amp;gt; ianimal = igiraffe; // interface is covariant in T&lt;BR&gt;ianimal.M&amp;lt;Turtle&amp;gt;(); // satisifies the constraint that U must be an Animal.&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Uh oh. ianimal is really an instance of&amp;nbsp;C&amp;lt;Giraffe&amp;gt;.&amp;nbsp;The M&amp;lt;U&amp;gt; method on C&amp;lt;Giraffe&amp;gt; inherits a requirement that U inherit from Giraffe. Turtle does not inherit from Giraffe. Therefore we've just violated the constraint on M&amp;lt;U&amp;gt;. The only places where we can catch this is in the declaration; every other step is&amp;nbsp;perfectly legal. Therefore, a constraint cannot be covariant. But if we make it contravariant (or invariant) then it all works out. For example, let's make a contravariant type parameter constraint:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;interface I2&amp;lt;in T&amp;gt; // contravariant this time&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; void M&amp;lt;U&amp;gt;() where U : T; &lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;class C2&amp;lt;T&amp;gt; : I2&amp;lt;T&amp;gt; { public void M&amp;lt;U&amp;gt;() {} }&lt;BR&gt;I2&amp;lt;Animal&amp;gt; i2animal = new C2&amp;lt;Animal&amp;gt;();&amp;nbsp;// C2&amp;lt;T&amp;gt; implements I2&amp;lt;T&amp;gt;&lt;BR&gt;I2&amp;lt;Mammal&amp;gt; i2mammal = i2animal; // interface is contravariant in T&lt;BR&gt;i2mammal.M&amp;lt;Giraffe&amp;gt;(); // satisifies the constraint that U must be an Animal.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;And now everything is fine; the compile-time constraint checker verifies that Giraffe is Mammal; at runtime it must be Animal,&amp;nbsp;and so the compiler has verified that by verifying that&amp;nbsp;it is Mammal.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The rules for &lt;STRONG&gt;delegate declarations&lt;/STRONG&gt; are a straightforward simplification of the rules for interface declarations. To be a valid delegate declaration, the return type must be valid covariantly (or void), the formal parameter types must be valid contravariantly (or invariantly if they are out/ref), and any type parameter constraints must be valid contravariantly. &lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9923708" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/default.aspx">Covariance and Contravariance</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_+4.0/default.aspx">C# 4.0</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Language+Design/default.aspx">Language Design</category></item><item><title>What's the difference between covariance and assignment compatibility?</title><link>http://blogs.msdn.com/ericlippert/archive/2009/11/30/what-s-the-difference-between-covariance-and-assignment-compatibility.aspx</link><pubDate>Mon, 30 Nov 2009 14:51:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9923199</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>18</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9923199.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9923199</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;I've written a lot about this already, but I think one particular point bears repeating.&lt;/P&gt;
&lt;P&gt;As we're getting closer to shipping C# 4.0, I'm seeing a lot of documents, blogs, and so on, attempting to explain what "covariant" means. This is a tricky word to define in a way that is actually meaningful to people who haven't already got degrees in category theory, but it can be done. And I think it's important to avoid defining a word to mean something other than its actual meaning.&lt;/P&gt;
&lt;P&gt;A number of those documents have led with something like:&lt;/P&gt;
&lt;P&gt;"Covariance is the ability to assign an expression of a more specific type to a variable of a less specific type. For example, consider a method M that returns a Giraffe. You can assign the result of M to a variable of type Animal, because Animal is a less specific type that is compatible with Giraffe. Methods in C# are 'covariant' in their return types, which is why when you create a covariant interface, it is indicated with the keyword 'out' -- the returned value comes 'out' of the method."&lt;/P&gt;
&lt;P&gt;But that's &lt;STRONG&gt;not at all&lt;/STRONG&gt; what covariance means. That's describing "assignment compatibility" -- the ability to assign a value of a more specific type to a storage of a compatible, less specific type is called "assignment compatibility" because the two types are compatible for the purposes of verifying legality of assignments.&lt;/P&gt;
&lt;P&gt;So what does covariance mean then?&lt;/P&gt;
&lt;P&gt;First off, we need to work out precisely what the adjective "covariant" applies to. I'm going to get more formal for a bit here, but try to keep it understandable.&lt;/P&gt;
&lt;P&gt;Let's start by not even considering types. Let's think about integers. (And here I am speaking of actual mathematical integers, not of the weird behaviour of 32-bit integers in unchecked contexts.) Specifically, we're going to think about the ≤ relation on integers, the "less than or equal to" relation. (Recall that of course a "relation" is a function which takes two things and returns a bool which indicates whether the given relationship holds or does not hold.)&lt;/P&gt;
&lt;P&gt;Now let's think about a projection on integers. What is a projection? A projection is a function which takes a single integer and returns a new integer. So, for example, z → z + z is a projection; call it D for "double".&amp;nbsp; So are z → 0 - z, N for "negate" and z → z * z, S for "square".&lt;/P&gt;
&lt;P&gt;Now, here's an interesting question. Is it always the case that (x ≤ y) = (D(x) ≤ D(y))?&amp;nbsp; Yes, it is. If x is less than y, then twice x is less than twice y. If x is equal to y then twice x is equal to twice y. And if x is greater than y, then twice x is greater than twice y. The projection D preserves the direction of size.&lt;/P&gt;
&lt;P&gt;What about N? Is it always the case that (x ≤ y) = (N(x) ≤ N(y))?&amp;nbsp; Clearly not. 1 ≤ 2 is true, but -1 ≤ -2 is false. But we notice that the reverse is always true!&amp;nbsp; (x ≤ y) = (N(y) ≤ N(x)). The projection N reverses the direction of size.&lt;/P&gt;
&lt;P&gt;What about S? Is it always the case that (x ≤ y) = (S(x) ≤ S(y))? No. -1 ≤ 0 is true, but S(-1) ≤ S(0) is false. What about the opposite? Is it always the case that (x ≤ y) = (S(y) ≤ S(x)) ? Again, no. 1 ≤ 2 is true, but S(2) ≤ S(1) is false. The projection S does not preserve the direction of size, and nor does it reverse it. &lt;/P&gt;
&lt;P&gt;The projection D is "covariant" -- it preserves the ordering relationship on integers. The projection N is "contravariant". It reverses the ordering relationship on integers. The projection S does neither; it is "invariant".&lt;/P&gt;
&lt;P&gt;Now I hope it is more clear exactly what is covariant or contravariant. The integers themselves are not variant, and the "less than" relationship is not variant. It's &lt;STRONG&gt;the projection&lt;/STRONG&gt; that is covariant or contravariant -- the rule for taking an old integer and making a new one out of it.&lt;/P&gt;
&lt;P&gt;So now lets abandon integers and think about reference types. Instead of the ≤ relation on integers, we have the ≤ relation on reference types. A reference type X is smaller than (or equal to) a reference type Y if a value of type X can be stored in a variable of type Y. That is, if X is "assignment compatible" with Y.&lt;/P&gt;
&lt;P&gt;Now consider a projection from types to types. Say, the projection "T goes to IEnumerable&amp;lt;T&amp;gt;".&amp;nbsp; That is, we have a projection that takes a type, say, Giraffe, and gives you back a new type, IEnumerable&amp;lt;Giraffe&amp;gt;. Is that projection covariant in C# 4?&amp;nbsp; Yes. It preserves the direction of ordering. A Giraffe may be assigned to a variable of type Animal, and therefore an sequence of Giraffes may be assigned to a variable that can hold a sequence of Animals.&lt;/P&gt;
&lt;P&gt;We can think of generic types as "blueprints" that produce constructed types. Let's take the projection that takes a type T and produces IEnumerable&amp;lt;T&amp;gt; and simply call that projection "IEnumerable&amp;lt;T&amp;gt;". We can understand from context when we say "IEnumerable&amp;lt;T&amp;gt; is covariant" what we mean is "the projection which takes a reference type T and produces a reference type IEnumerable&amp;lt;T&amp;gt; is a covariant projection". And since IEnumerable&amp;lt;T&amp;gt; only has one type parameter, it is clear from the context that we mean that the parameter to the projection is T. After all, it is a lot shorter to say "IEnumerable&amp;lt;T&amp;gt; is covariant" than that other mouthful.&lt;/P&gt;
&lt;P&gt;So now we can define covariance, contravariance and invariance. A generic type I&amp;lt;T&amp;gt; is &lt;STRONG&gt;covariant&lt;/STRONG&gt; (in T) if construction with reference type arguments &lt;STRONG&gt;preserves&lt;/STRONG&gt; the direction of assignment compatibility. It is &lt;STRONG&gt;contravariant&lt;/STRONG&gt; (in T) if it &lt;STRONG&gt;reverses&lt;/STRONG&gt; the direction of assignment compatibility. And it is &lt;STRONG&gt;invariant&lt;/STRONG&gt; if it does neither. And by that, we simply are saying in a concise way that the &lt;STRONG&gt;projection&lt;/STRONG&gt; which takes a T and produces I&amp;lt;T&amp;gt; is a covariant/contravariant/invariant projection.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;UPDATE: My close personal friend (and fellow computer geek)&amp;nbsp;Jen notes that in the Twilight series of novels, the so-called "werewolves" (who are not transformed by the full moon and therefore not actually werewolves) maintain their rigid social ordering in both wolf and human form; the projection from human to wolf is covariant in the social-ordering relation. She also notes that in high school, programming language geeks are at the bottom of the social order, but the projection to adulthood catapults them to the top of the social order, and therefore, growing up is contravariant. I am somewhat skeptical of the latter claim; the former, I'll take your word for it. I suppose the question of how social order works amongst teenage werewolves who are computer geeks is a subject for additional research. Thanks Jen!&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9923199" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Rarefied+Heights/default.aspx">Rarefied Heights</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/default.aspx">Covariance and Contravariance</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_+4.0/default.aspx">C# 4.0</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/What_2700_s+The+Difference_3F00_/default.aspx">What's The Difference?</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/werewolves/default.aspx">werewolves</category></item><item><title>The Purpose, Revealed</title><link>http://blogs.msdn.com/ericlippert/archive/2009/11/25/the-purpose-revealed.aspx</link><pubDate>Wed, 25 Nov 2009 17:03:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9928668</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>8</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9928668.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9928668</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;Interestingly enough, no one correctly guessed why I needed code in the compiler to transform a method argument list into a form that batched up the side effecting expressions, stuck their values in variables, and then called the method with the side-effect-free variable references. There certainly were some fascinating ideas in the comments though!&lt;/P&gt;
&lt;P&gt;The reason is quite mundane. We had a bug in the code that performs semantic analysis of calls with named arguments. One of our rules in C# that I've talked about a lot on this blog is that sub-expression evaluation occurs in left-to-right order. If you have a method &lt;SPAN class=code&gt;void&amp;nbsp;M(int&amp;nbsp;x,&amp;nbsp;int&amp;nbsp;y)&amp;nbsp;{} &lt;/SPAN&gt;and then a call site &lt;SPAN class=code&gt;M(y&amp;nbsp;:&amp;nbsp;F(),&amp;nbsp;x&amp;nbsp;:&amp;nbsp;G());&lt;/SPAN&gt; we cannot simply generate the code as though you'd written &lt;SPAN class=code&gt;M(G(),&amp;nbsp;F())&lt;/SPAN&gt;. The side effects of F have to happen before the side effects of G, so we generate code as though you'd said &lt;SPAN class=code&gt;temp1&amp;nbsp;=&amp;nbsp;F(); temp2&amp;nbsp;=&amp;nbsp;G(); M(y&amp;nbsp;:&amp;nbsp;temp1,&amp;nbsp;x&amp;nbsp;:&amp;nbsp;temp2);&lt;/SPAN&gt; and now we can generate the call as &lt;SPAN class=code&gt;M(temp2,&amp;nbsp;temp1);&lt;/SPAN&gt; without worrying about re-ordering a side effect. &lt;/P&gt;
&lt;P&gt;The bug was that the rewriter was not getting the reordering correct if the parameters were ref/out or the arguments were locals without side effects. As I often do when fixing a bug, I reasoned that the initial bug had been caused because the rewriter was under-specified. &lt;/P&gt;
&lt;P&gt;The fix will get into the initial release of C# 4, but the problems that Pavel identified with it -- that certain obscure side effects such as the order in which bad array accesses throw exceptions, or the order in which static class constructors execute, are not correctly preserved by my algorithm, will not be fixed for the initial release. Doing these correctly requires us to be able to generate temporaries of "reference to argument" types, which we've never done before and which our IL generator was not built to handle. Had we discovered the bug much earlier in the cycle, we probably could have applied a more solid fix, but it is too late now. &lt;/P&gt;
&lt;P&gt;Thanks again to Pavel for the great analysis, and thanks to our old friend nikov for reporting the bug in the first place. &lt;/P&gt;
&lt;P&gt;And happy thanksgiving to my readers in the United States! As I do every year, I'm roasting a turkey to feed fourteen people. I highly recommend the "brine the bird then&amp;nbsp;roast it upside-down" method described in The Joy Of Cooking. It's worked perfectly&amp;nbsp;for me for the last ten years straight.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9928668" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Code+Generation/default.aspx">Code Generation</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Software+development+methodology/default.aspx">Software development methodology</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_+4.0/default.aspx">C# 4.0</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Language+Design/default.aspx">Language Design</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/named+parameters/default.aspx">named parameters</category></item><item><title>Always write a spec, Part Two</title><link>http://blogs.msdn.com/ericlippert/archive/2009/11/23/always-write-a-spec-part-two.aspx</link><pubDate>Mon, 23 Nov 2009 15:01:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9921574</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>19</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9921574.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9921574</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;Upon submitting that specification for review, even before seeing my code, Chris found a bug and an omission.&lt;/P&gt;
&lt;P&gt;The omission is that I neglected to say what happens when the ref variable is an index into a fixed-size array buffer. As it turns out, that case is also rewritten as a pointer dereference by the time we get to this point in the code, so missing that case turned out to not be a big deal.&lt;/P&gt;
&lt;P&gt;The bug is that this line is wrong:&lt;/P&gt;
&lt;HR&gt;

&lt;DIV class=spec&gt;
&lt;P&gt;if x is ref/out instance.field then&amp;nbsp;add var temp=instance&amp;nbsp;to&amp;nbsp;L and ref/out temp.field to A2. &lt;/P&gt;&lt;/DIV&gt;
&lt;HR&gt;

&lt;P&gt;because it does not meet the stated goal of the method,&amp;nbsp;namely, to&amp;nbsp;produce the same results after the transformation:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;struct S { public int q; }&lt;BR&gt;static void M(ref int r) { r = r + 1; }&lt;BR&gt;static int Zero() { Console.WriteLine("hello!"); return 0; }&lt;BR&gt;...&lt;BR&gt;S[] arr = new[] { new S() };&lt;BR&gt;M(ref arr[Zero()].q);&lt;BR&gt;Console.WriteLine(arr[0].q); // 1&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Here we have a variable expression of the form instance.field which has a side effect; it prints "Hello". So according to the spec, we rewrite that as&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;S&amp;nbsp;temp = arr[Zero()];&lt;BR&gt;M(ref temp.q);&lt;BR&gt;Console.WriteLine(arr[0].q); // 0 !&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Once more, mutable value types are revealed to be pure concentrated evil. We just mutated temp.q, which is a &lt;EM&gt;copy&lt;/EM&gt; of arr[0].&lt;/P&gt;
&lt;P&gt;The interesting thing here is that Chris found the bug by &lt;STRONG&gt;reading the spec&lt;/STRONG&gt; and thinking about whether I'd missed any interesting cases. Bugs are always cheaper to fix the earlier you find them; a bug you fix as a result of reading the spec is a bug that you don't have to pay QA to find, it's a bug that your customers never see, it's a bug that never causes a backwards-compatibility breaking change, and so on.&lt;/P&gt;
&lt;P&gt;I thought hard about this and realized that the painful case only happens when we have ref/out instance.field with a side effect and &lt;STRONG&gt;instance is a variable of value type&lt;/STRONG&gt;. That's the missing case. Furthermore, we can solve this by recursing!&lt;/P&gt;
&lt;HR&gt;

&lt;DIV class=spec&gt;
&lt;UL&gt;
&lt;LI&gt;if x is ref/out instance.field and&amp;nbsp;instance is&amp;nbsp;a variable of value type, then recurse. Compute T("ref instance"), as if we were invoking a method that takes a single parameter of this ref type. That will give us a resulting declaration list, which we merge onto the end of L, and a resulting argument list with one element on it, r. Add "ref r.field" to A2.&lt;/LI&gt;
&lt;LI&gt;if x is a ref/out instance.field but instance is not a variable of value type, then generate var temp=instance on L, &amp;nbsp;ref temp.field on A2.&lt;/LI&gt;&lt;/UL&gt;&lt;/DIV&gt;
&lt;HR&gt;

&lt;P&gt;So if we have, say, &lt;SPAN class=code&gt;M(ref arr[index].q)&lt;/SPAN&gt;, that ultimately is generated as &lt;SPAN class=code&gt;var t1 = arr, var t2 = index, M(ref t1[t2].q)&lt;/SPAN&gt;, which is correct.&lt;/P&gt;
&lt;P&gt;I fixed up my implementation, wrote some test cases to test the spec, and sent it off to testing for further analysis.&lt;/P&gt;
&lt;P&gt;There's &lt;EM&gt;still&lt;/EM&gt; a bug in this spec, which our tester David found during his analysis of my spec plus proposed implementation. Hint: the problem has nothing to do with ref/out semantics; it's a more fundamental error in reasoning.&lt;/P&gt;
&lt;P&gt;Feel free to pause and reflect for a moment if you want a chance to figure it out for yourself.&lt;/P&gt;
&lt;P&gt;...&lt;/P&gt;
&lt;P&gt;The error is in the default case:&lt;/P&gt;
&lt;HR&gt;

&lt;DIV class=spec&gt;
&lt;P&gt;First, if x has no side effects, then simply keep x in the appropriate place in A2.&lt;/P&gt;&lt;/DIV&gt;
&lt;HR&gt;

&lt;P&gt;Whether x has side effects or not is completely irrelevant; what is relevant is whether the computation of x depends on the order of every other side effect!&lt;/P&gt;
&lt;P&gt;For example, our spec would have that &lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;int k = 0;&lt;BR&gt;M( k, arr[k=1] );&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;is the same as&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;int k = 0;&lt;BR&gt;var t1&amp;nbsp;= arr;&lt;BR&gt;var&amp;nbsp;t2 = (k = 1);&lt;BR&gt;M(k,&amp;nbsp;t1[t2]);&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;which is clearly not correct; the first argument&amp;nbsp;is supposed to be zero, not one. The fact that the first argument has no side effects is irrelevant; it depends on the second argument's side effect taking effect &lt;EM&gt;after&lt;/EM&gt; the first argument's &lt;EM&gt;value&lt;/EM&gt; is computed.&lt;/P&gt;
&lt;P&gt;We have to fix up the spec (and implementation) to say that if the argument corresponds to a &lt;EM&gt;value&lt;/EM&gt; parameter, you &lt;EM&gt;always&lt;/EM&gt; save away the value in a temporary, regardless of whether it has side effects or not. If it corresponds to, say, a ref parameter, and the argument is a ref to a local then we can still simply generate the ref to the local normally; regardless of whether the contents of the local change, the managed address of the local is always the same, and computing the address of a local causes no side effects.&lt;/P&gt;
&lt;P&gt;I note that we could also make an exception in the case that the value is, say, a compile-time constant. Clearly the computation of its value does not have any dependency on the ordering of other side effects. But for the sake of not further complexifying my spec and implementation, I glossed over this detail. The optimizer will probably take care of it.&lt;/P&gt;
&lt;P&gt;Commenter Pavel Minaev found several more corner cases&amp;nbsp;that none of us found. The big one is that we should be clear about what happens with multidimensional arrays, and in fact, I had a bug in my implementation for multidimensional arrays, so thanks Pavel! He also found some obscure ones. One is that accessing a static field does have a side effect; if this is the first access to the class then&amp;nbsp;that causes the static class constructor to run, which could have observable side effects.&amp;nbsp;Another is that the exact semantics of when bad arguments cause exceptions is slightly changed by this transformation.&lt;/P&gt;
&lt;P&gt;At this point I now believe that I have a correct specification of my function T (modulo Pavel's weird issues, which I'm still mulling over. But those are bizarre corner cases that might require some language spec work to sort out.) Since the implementation is a straightforward transformation of the specification into C++, I also believe I have a correct implementation. I've written test cases that verify every case in the spec, and handed it off to testing to look for practical cases I missed.&lt;/P&gt;
&lt;P&gt;Anyone see any other problems with this spec? Anyone?&lt;/P&gt;
&lt;P&gt;And anyone have any guesses as to why I needed this function implemented?&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=9921574" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Code+Quality/default.aspx">Code Quality</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Software+development+methodology/default.aspx">Software development methodology</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Value+Types/default.aspx">Value Types</category></item><item><title>Always write a spec, part one</title><link>http://blogs.msdn.com/ericlippert/archive/2009/11/19/always-write-a-spec-part-one.aspx</link><pubDate>Thu, 19 Nov 2009 14:45:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9921545</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>27</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9921545.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9921545</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;Joel had a great series of articles many years ago about &lt;A href="http://www.joelonsoftware.com/articles/fog0000000036.html" mce_href="http://www.joelonsoftware.com/articles/fog0000000036.html"&gt;the benefits of writing functional specifications&lt;/A&gt;, that is, specifications of how the product looks to its users. I want to talk a bit about technical specifications, that is, a specification of how something actually works behind the scenes. A while back, I described how I wrote a seemingly-trivial piece of code by &lt;A href="http://blogs.msdn.com/ericlippert/archive/2009/06/01/bug-psychology.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2009/06/01/bug-psychology.aspx"&gt;first writing the technical spec, and then writing the code to exactly implement the spec&lt;/A&gt;, and the test cases to test each statement of the spec. I use this technique frequently; it almost always saves me time and effort. If you don't write a spec first, it's very easy to get bogged down in a morass of bugs, and hard to know when you're actually done writing the code.&lt;/P&gt;
&lt;P&gt;Here's an example of another seemingly-trivial function that &lt;A href="http://stackoverflow.com/questions/921180/c-round-up/926806#926806" mce_href="http://stackoverflow.com/questions/921180/c-round-up/926806#926806"&gt;smart people gave a good half-dozen completely wrong answers to because they didn't write a spec&lt;/A&gt;. Notice how once I state what the spec is, the code follows very naturally.&lt;/P&gt;
&lt;P&gt;I thought I might go through a recent example of a slightly less trivial problem. I needed a function in the compiler which could take a valid list of arguments A1 to an applicable method M, and give me back two lists. The first result list is a list of &lt;EM&gt;local variable declarations&lt;/EM&gt;, L, the second, another argument list, A2. Here's the kicker: evaluating each member of A2 &lt;EM&gt;must have no side effects&lt;/EM&gt;. And, the combination of executing L followed by M(A2) must give &lt;EM&gt;exactly the same results&lt;/EM&gt; as executing M(A1). (I also knew that the members of A1 had already had all the conversions generated to make them match the types of M's parameter list, and so on. Overload resolution was completely done at this point.)&lt;/P&gt;
&lt;P&gt;Why I needed such a function is not particularly important; perhaps you can speculate as to why I needed it.&lt;/P&gt;
&lt;P&gt;So I started writing a spec, starting with the description above: the function T takes a valid list... blah blah blah.&lt;/P&gt;
&lt;P&gt;That's not enough of a spec to actually write code. &lt;/P&gt;
&lt;P&gt;I realized that some expressions in A1 might have side effects, and some might not. If an expression had side effects, then I could declare a temp local, execute the side effects, assign the result to the local, and then use the local as the expression in the same place in A2.&lt;/P&gt;
&lt;P&gt;Super. Now I can write more sentences in my spec.&lt;/P&gt;
&lt;HR&gt;

&lt;DIV class=spec&gt;
&lt;P&gt;For each argument x in A1, we potentially generate a temporary value as follows: First, if x has no side effects, then simply keep x in the appropriate place in A2. Otherwise, if x does have side effects, then generate a temporary variable declaration in L, var temp = x. Then put an expression that evaluates the temporary variable in the appropriate place in A2.&lt;/P&gt;&lt;/DIV&gt;
&lt;HR&gt;

&lt;P&gt;Then I thought "can I correctly implement this spec?"&lt;/P&gt;
&lt;P&gt;I started thinking about the possible cases for the input, A1. The members of A1 could be passed by value, out, or ref; I already knew they were correct, since the particular method M was an applicable method of argument list A1. In this particular point in the compilation process, there was no need to worry about whether there were "params" arguments, whether there were missing arguments with default values, and so on; that had already been taken care of. I also noted that whether they were "ref" or "out" was irrelevant; ref and out are the same thing behind the scenes. As far as the compiler is concerned, the only difference between them is that the definite assignment rules are different for each.&amp;nbsp;So we had two cases for each argument: it's being passed by value, or by ref/out. &lt;/P&gt;
&lt;P&gt;If it's being passed by ref/out, then what we actually do is we pass&amp;nbsp;the managed address of&amp;nbsp;a variable to the method. In M(ref int x), the type of x is actually a special type int&amp;amp;, "managed reference to variable of type int", which is not a legal type in C#. That's why we hide it from you by requiring a goofy "ref" syntax any time you want to talk about a managed reference to a variable.&lt;/P&gt;
&lt;P&gt;Unfortunately, our IL generation pass was written with the assumption that all local variables are never of these magic managed-reference-to-variable types. I was then faced with a choice. Either come up with a technique for working with this limitation, or rewrite the most complicated code in the IL gen to support this scenario. (The code which figures out how to deal with managed references is quite complex.) I decided to opt for the former strategy. Which meant more spec work, since our spec now doesn't handle these cases!&lt;/P&gt;
&lt;HR&gt;

&lt;DIV class=spec&gt;
&lt;P&gt;For each argument x in A1, we potentially generate a temporary value as follows: &lt;/P&gt;
&lt;P&gt;First, if x has no side effects, then simply keep x in the appropriate place in A2. &lt;/P&gt;
&lt;P&gt;Otherwise, if x does have side effects &lt;STRONG&gt;and corresponds to a value parameter&lt;/STRONG&gt;, then generate ... etc.&lt;/P&gt;
&lt;P&gt;Otherwise, if x does have side effects and corresponds to a ref/out parameter, &lt;STRONG&gt;then a miracle happens&lt;/STRONG&gt;.&lt;/P&gt;&lt;/DIV&gt;
&lt;HR&gt;

&lt;P&gt;Clearly that last bit needed some work.&lt;/P&gt;
&lt;P&gt;So I wrote down all the possible cases I could think of. Clearly x has to be a variable if its type is "reference to variable", so that makes for a small number of cases:&lt;/P&gt;
&lt;HR&gt;

&lt;DIV class=spec&gt;
&lt;P&gt;Otherwise, if x does have side effects and corresponds to a ref/out parameter, then the possible cases are:&lt;/P&gt;
&lt;P&gt;* x is a local variable&lt;BR&gt;* x is a value parameter&lt;BR&gt;* x is an out parameter&lt;BR&gt;* x is a ref parameter&lt;BR&gt;* x is a field of an instance&lt;BR&gt;* x is a static field&lt;BR&gt;* x is an array element&lt;BR&gt;* x is a pointer dereferenced with *&lt;BR&gt;* x is a pointer dereferenced with [ ]&lt;/P&gt;
&lt;P&gt;and for each, a miracle happens.&lt;/P&gt;&lt;/DIV&gt;
&lt;HR&gt;

&lt;P&gt;Again, clearly this is not good enough. I re-examined my list to see if I could eliminate any of these cases. Locals, parameters and&amp;nbsp;static fields never have side effects, so we can eliminate them.&lt;/P&gt;
&lt;P&gt;Also, at this point in our analysis, I knew that pointer dereferences of the form "pointer[index]" had already been rewritten into the form "*(pointer + index)", which meant that in practice, we would never actually hit that last case in this algorithm; the second-last case would take care of both.&lt;/P&gt;
&lt;HR&gt;

&lt;DIV class=spec&gt;
&lt;P&gt;Otherwise, if x does have side effects and corresponds to a ref/out parameter, then the possible cases are:&lt;/P&gt;
&lt;P&gt;* x is a field of an instance&lt;BR&gt;* x is an array element&lt;BR&gt;* x is a pointer dereferenced with *&lt;BR&gt;&lt;BR&gt;and for each, a miracle happens.&lt;/P&gt;&lt;/DIV&gt;
&lt;HR&gt;

&lt;P&gt;I then started to think of what side effects could happen for each.&amp;nbsp;We could have "ref instance.field", "ref array[index]", or "ref *pointer", and&amp;nbsp;"instance", "array", "index" and "pointer" can all be expressions that have a&amp;nbsp;side effect. ("field" cannot, it merely names a field.) So now we can use the same specification as before:&lt;/P&gt;
&lt;HR&gt;

&lt;P class=spec&gt;Otherwise, if x does have side effects and corresponds to a ref/out parameter, then the possible cases are:&lt;/P&gt;
&lt;DIV class=spec&gt;
&lt;UL&gt;
&lt;LI&gt;x is ref/out instance.field: in this case,&amp;nbsp;add var temp=instance&amp;nbsp;to&amp;nbsp;L and ref/out temp.field to A2.&lt;/LI&gt;
&lt;LI&gt;x is ref/out array[index]: in this case, add var t1 = array and&amp;nbsp;var t2 = index to L and ref/out t1[t2] to A2.&lt;/LI&gt;
&lt;LI&gt;x is ref/out *pointer: in this case, add var temp = pointer to L and ref/out *temp to A2.&lt;/LI&gt;&lt;/UL&gt;&lt;/DIV&gt;
&lt;HR&gt;

&lt;P&gt;And now we have something I can implement. So I sent this proposed spec around for review, while I started plugging away at the implementation.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;This spec is wrong.&lt;/STRONG&gt; Can you spot the&amp;nbsp;bugs in my implementation&amp;nbsp;that my coworkers found by reading my spec?&lt;/P&gt;
&lt;P&gt;Next time, the thrilling conclusion.&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=9921545" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Puzzles/default.aspx">Puzzles</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Code+Quality/default.aspx">Code Quality</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Software+development+methodology/default.aspx">Software development methodology</category></item><item><title>Closing over the loop variable, part two</title><link>http://blogs.msdn.com/ericlippert/archive/2009/11/16/closing-over-the-loop-variable-part-two.aspx</link><pubDate>Mon, 16 Nov 2009 16:18:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9923025</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>42</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9923025.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9923025</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;Thanks to everyone who left thoughtful and insightful comments on last week's post.&lt;/P&gt;
&lt;P&gt;More countries&amp;nbsp;really ought to implement Instant Runoff Voting; it would certainly appeal to the geek crowd. Many people left complex opinions of the form "I'd prefer to make the change, but if you can't do that then make it a warning". Or "don't make the change, do make it a warning", and so on.&amp;nbsp;But what I can deduce from reading the comments is that there is a general lack of consensus on what the right thing to do here is. In fact, I just did a quick tally:&lt;/P&gt;
&lt;P&gt;Commenters who expressed support for a warning: 26&lt;BR&gt;Commenters who expressed the sentiment "it's better to not make the change": 24&lt;BR&gt;Commenters who expressed the sentiment "it's better to make the change": 25&lt;/P&gt;
&lt;P&gt;Wow. I guess we'll flip a coin. :-)&amp;nbsp;&amp;nbsp;&amp;nbsp; (*)&lt;/P&gt;
&lt;P&gt;Four people suggested to actually make it an error to do this. That's a pretty big breaking change, particularly since we would be breaking not just "already broken" code, but plenty of code that works perfectly well today -- see below. That's not likely to happen.&lt;/P&gt;
&lt;P&gt;People also left a number of interesting suggestions. I thought I'd discuss some of those a little bit.&lt;/P&gt;
&lt;P&gt;First off, I want to emphasize that what we're attempting to address here is the problem that &lt;STRONG&gt;the language encourages people to write code that has different semantics than they think it has&lt;/STRONG&gt;. The problem is NOT that the language has no way to express the desired semantics; clearly it does. Just introduce a new variable explicitly into the loop.&lt;/P&gt;
&lt;P&gt;A number of suggestions were for ways that the language could more elegantly express that notion. Some of the suggestions:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;foreach(var x in c) &lt;STRONG&gt;inner&lt;/STRONG&gt; &lt;BR&gt;&lt;STRONG&gt;foreachnew&lt;/STRONG&gt;(var x in c)&lt;BR&gt;foreach(&lt;STRONG&gt;new&lt;/STRONG&gt; var x in c)&lt;BR&gt;foreach(var x&amp;nbsp;&lt;STRONG&gt;from&lt;/STRONG&gt; c) &lt;BR&gt;foreach(var x&amp;nbsp;&lt;STRONG&gt;inside&lt;/STRONG&gt; c) &lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Though we could do any of those, none of them by themselves solve the problem at hand. Today, you have to know to use a particular pattern with foreach to get the semantics you want: declare a variable inside the loop. With one of these changes, you still have to know to use a particular keyword to get the semantics you want, and it is still easy to accidentally do the wrong thing. &lt;/P&gt;
&lt;P&gt;Furthermore,&amp;nbsp;a change so small and so targetted at such a narrow scenario probably does not provide enough benefit to justify the large cost of creating a new syntax, particularly one which is still easily confused with an existing syntax.&lt;/P&gt;
&lt;P&gt;C++ luminary Herb Sutter happened to be in town and was kind enough to stop by my office to describe to me how they are solving a related problem in C++. Apparently the next version of the C++ standard will include lambdas, and they're doing this:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;&lt;EM&gt;[q, &amp;amp;r]&lt;/EM&gt; &lt;STRONG&gt;(int x) -&amp;gt; int&lt;/STRONG&gt; { return M(x, q, r); }&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;This means that the lambda captures outer variable q by value, captures r by reference, takes an int and returns an int. Whether the lambda captures values or references is controllable! An interesting approach but one that doesn't immediately solve our problem here; we cannot make lambdas capture by value by default without a huge breaking change. Capturing by value would have to require new syntax, and then we're in the same boat again: the user has to know to use the new syntax when in a foreach loop.&lt;/P&gt;
&lt;P&gt;A number of people also asked what the down sides of adding a warning are. The down side is that &lt;STRONG&gt;a warning which warns about correct behaviour is a very bad warning&lt;/STRONG&gt;; it makes people change working code, and frequently they break working code in order to eliminate a warning that shouldn't have been present in the first place. Consider:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;foreach(var insect in insects)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; var query = frogs.Where(frog=&amp;gt;frog.Eats(insect));&lt;BR&gt;&amp;nbsp; Console.WriteLine("{0} is eaten by {1} frogs.", insect, query.Count());&lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;This makes a lambda closed over insect; the lambda never escapes the loop, so there's no problem here. But the compiler doesn't know that. The compiler sees that the lambda is being passed to a method called Where, and Where is allowed to do anything with that delegate, including storing it away to be called later. Which is exactly what Where does! Where stores away the lambda into a monad that represents the execution of the query. The fact that the &lt;STRONG&gt;query object doesn't survive the loop&lt;/STRONG&gt; is what keeps this safe. But how is the compiler supposed to suss out that tortuous chain of reasoning? We'd have to give a warning for this case, even though it is perfectly safe. &lt;/P&gt;
&lt;P&gt;It gets worse. A lot of people are required by their organizations to compile with "warnings are errors" turned on. Therefore, any time we introduce a new warning for a pattern that is often actually safe and frequently used, we are effectively causing an enormous breaking change. A vaccine which kills more healthy people than the disease would have is probably not a good bet. (**)&lt;/P&gt;
&lt;P&gt;This is not to say that a warning is a bad idea, but that it is not the obvious slam dunk good idea that it initially appears to be.&lt;/P&gt;
&lt;P&gt;A number of people suggested that the problem was in the training of the developers, not in the design of the language. I disagree. Obviously modern languages are complex tools that require training to use, but we are working hard to make a language where people's natural intuitions about how things work lead them to write correct code. I have myself made this error a number of times, usually in the form of writing code like the code above, and then refactoring it in such a manner that suddenly some part of it escapes the loop and the bug is introduced. It is very easy to make this mistake, even for experienced developers who thoroughly understand closure semantics. That's a flaw in the design of the language. &lt;/P&gt;
&lt;P&gt;And finally, a number of people made suggestions of the form "make it a warning in C# 4, and an error in C# 5", or some such thing. FYI, C# 4 is DONE. We are only making a few last-minute "user is electrocuted"-grade bug fixes, mostly based on your excellent feedback from the betas. (If you have bug reports from the beta, please keep sending them, but odds are good they won't get fixed for the initial release.) We are certainly not capable of introducing any sort of major design change or new feature at this point. And we try to not introduce semantic changes or new features in service packs. We're going to have to live with this problem for at least another cycle, unfortunately.&lt;/P&gt;
&lt;P&gt;********&lt;/P&gt;
&lt;P&gt;(*) Mr. Smiley Face indicates that Eric is indulging in humourous japery.&lt;/P&gt;
&lt;P&gt;(**) I wish to emphasize that I am 100% in favour of vaccinations for deadly infectious&amp;nbsp;diseases, &lt;EM&gt;even vaccines that are potentially dangerous&lt;/EM&gt;. The number of people made ill or killed by the smallpox vaccine was tiny compared to the number of people who did not contract this deadly, contagious (and now effectively extinct)&amp;nbsp;disease as a result of mass vaccination. I am a strong supporter of vaccine research. I'm just making an analogy here people.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9923025" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Breaking+Changes/default.aspx">Breaking Changes</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Lambda+Expressions/default.aspx">Lambda Expressions</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/foreach/default.aspx">foreach</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/closures/default.aspx">closures</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/coin+flipping/default.aspx">coin flipping</category></item><item><title>Closing over the loop variable considered harmful</title><link>http://blogs.msdn.com/ericlippert/archive/2009/11/12/closing-over-the-loop-variable-considered-harmful.aspx</link><pubDate>Thu, 12 Nov 2009 14:50:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9918689</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>122</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9918689.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9918689</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;I don't know why I haven't blogged about this one before; this is the single most common incorrect bug report we get. That is, someone thinks they have found a bug&amp;nbsp;in the compiler, but in fact the compiler is correct and their code is wrong. That's a terrible situation for everyone; we very much wish to design a language which does not have "gotcha" features like this. &lt;/P&gt;
&lt;P&gt;But I'm getting ahead of myself. What's the output of this fragment?&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;var&amp;nbsp;values = new List&amp;lt;int&amp;gt;() { 100, 110, 120 };&lt;BR&gt;var&amp;nbsp;funcs = new List&amp;lt;Func&amp;lt;int&amp;gt;&amp;gt;();&lt;BR&gt;foreach(var v in values) &lt;BR&gt;&amp;nbsp; funcs.Add( ()=&amp;gt;v );&lt;BR&gt;foreach(var f&amp;nbsp;in funcs) &lt;BR&gt;&amp;nbsp; Console.WriteLine(f());&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Most people expect it to be 100 / 110 / 120.&amp;nbsp; It is in fact 120 / 120 / 120. Why?&lt;/P&gt;
&lt;P&gt;Because &lt;SPAN class=code&gt;()=&amp;gt;v&lt;/SPAN&gt; means "return &lt;STRONG&gt;the current value of variable v&lt;/STRONG&gt;", not "return the value v was back when the delegate was created". &lt;STRONG&gt;Closures close over variables, not over values.&lt;/STRONG&gt; And when the methods run, clearly the last value that was assigned to v was 120, so it still has that value.&lt;/P&gt;
&lt;P&gt;This is very confusing. The correct way to write the code is:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;foreach(var v in values) &lt;BR&gt;{&lt;BR&gt;&amp;nbsp; var v2 = v;&lt;BR&gt;&amp;nbsp; funcs.Add( ()=&amp;gt;v2 );&lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Now what happens? Every time we re-start the loop body, we logically create a fresh new variable v2. Each closure is closed over a different v2, which is only assigned to once, so it always keeps the correct value. &lt;/P&gt;
&lt;P&gt;Basically, the problem arises because we specify that the foreach loop is a syntactic sugar for&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;&amp;nbsp; {&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IEnumerator&amp;lt;int&amp;gt; e = ((IEnumerable&amp;lt;int&amp;gt;)values).GetEnumerator();&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; try&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int m; // OUTSIDE THE ACTUAL LOOP&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; while(e.MoveNext())&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m = (int)(int)e.Current;&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;funcs.Add(()=&amp;gt;m);&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; finally&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (e != null) ((IDisposable)e).Dispose();&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR minmax_bound="true"&gt;&amp;nbsp; }&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;If we specified that the expansion was&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; try&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; while(e.MoveNext())&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int m; // INSIDE&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m = (int)(int)e.Current;&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;funcs.Add(()=&amp;gt;m);&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;then the code would behave as expected.&lt;/P&gt;
&lt;P&gt;It's compelling to consider fixing this for a hypothetical future version of C#, and I'd like to hear your feedback on whether we should do so or not. The reasons FOR making the change are clear; this is a big confusing "gotcha" that real people constantly run into, and LINQ, unfortunately, only makes it worse, because it is likely to increase the number of times&amp;nbsp;a customer is going to use a closure in a loop. Also, it seems reasonable that the user of the&amp;nbsp;foreach loop&amp;nbsp;might&amp;nbsp;think of&amp;nbsp;there being&amp;nbsp;a "fresh" loop variable every time, not just a fresh value in the same old variable. Since the foreach loop variable is not mutable by user code, this reinforces the idea that it is a succession of values, one per loop iteration, and not "really" the same variable over and over again. And finally, the change has no effect whatsoever on non-closure semantics. (In fact, in C# 1 the spec was not clear about whether the loop variable went inside or outside, since in a world without closures, it makes no difference.)&lt;/P&gt;
&lt;P&gt;But that said, there are some very good reasons for not making this change.&lt;/P&gt;
&lt;P&gt;The first reason is that obviously this would be a breaking change, and we hates them, my precious. Any developers who depend on this feature, who require the closed-over variable to contain the last value of the loop variable, would be broken. I can only hope that the number of such people is vanishingly small; this is a strange thing to depend on. Most of the time, people do not expect or depend on this behaviour.&lt;/P&gt;
&lt;P&gt;Second, it makes the foreach syntax lexically inconsistent. Consider &lt;SPAN class=code&gt;foreach(int x in M())&lt;/SPAN&gt; The header of the loop has two parts, a declaration &lt;SPAN class=code&gt;int x&lt;/SPAN&gt; and a collection expression, &lt;SPAN class=code&gt;M()&lt;/SPAN&gt;. The &lt;SPAN class=code&gt;int x&lt;/SPAN&gt; is to the left of the &lt;SPAN class=code&gt;M()&lt;/SPAN&gt;. Clearly the &lt;SPAN class=code&gt;M()&lt;/SPAN&gt; is not inside the body of the loop; that thing only executes once, before the loop starts. So &lt;EM&gt;why should something to the collection expression's left be inside the loop&lt;/EM&gt;? This seems inconsistent with our general rule that stuff to the left logically "happens before" stuff to the right. The declaration is lexically NOT in the body of the loop, so why should we treat it as though it were?&lt;/P&gt;
&lt;P&gt;Third, it would make the "foreach" semantics inconsistent with "for" semantics. We have this same problem in "for" blocks, but "for" blocks are much looser about what "the loop variable" is; there can be more than one variable declared in the for loop header, it can be incremented in odd ways, and it seems implausible that people would consider each iteration of the "for" loop to contain a fresh crop of variables. When you say &lt;SPAN class=code&gt;for(int i; i &amp;lt; 10; i += 1)&lt;/SPAN&gt; it seems dead obvious that the "i += 1" means "increment the loop variable" and that there is one loop variable for the whole loop, not a new fresh variable "i" every time through! We certainly would not make this proposed change apply to "for" loops.&lt;/P&gt;
&lt;P&gt;And fourth, though this is a nasty gotcha, there is an easy workaround, and tools like ReSharper detect this pattern and suggest how to fix it. We could take a page from that playbook and simply&amp;nbsp;issue a compiler warning on this pattern. (Though adding new warnings brings up a whole raft of issues of&amp;nbsp;its own, which I might get into in another post.)&amp;nbsp;Though this is vexing, it really doesn't bite that many people that hard, and it's not a big deal to fix, so why go to the trouble and expense of taking a breaking change for something with an easy fix?&lt;/P&gt;
&lt;P&gt;Design is, of course, the art of compromise in the face of many competing principles. "Eliminate gotchas" in this case directly opposes other principles like "no breaking changes", and "be consistent with other language features". Any thoughts you have on pros or cons of us taking this breaking change in a hypothetical future version of C# would be greatly appreciated. &lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9918689" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Breaking+Changes/default.aspx">Breaking Changes</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Lambda+Expressions/default.aspx">Lambda Expressions</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Language+Design/default.aspx">Language Design</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/foreach/default.aspx">foreach</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/closures/default.aspx">closures</category></item><item><title>Three Umpires</title><link>http://blogs.msdn.com/ericlippert/archive/2009/11/09/three-umpires.aspx</link><pubDate>Mon, 09 Nov 2009 15:01:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9917417</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>11</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9917417.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9917417</wfw:commentRss><description>&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;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/baseball/default.aspx">baseball</category></item><item><title>Simple names are not so simple, Part Two, plus, volcanoes and fried foods</title><link>http://blogs.msdn.com/ericlippert/archive/2009/11/05/simple-names-are-not-so-simple-part-two.aspx</link><pubDate>Thu, 05 Nov 2009 14:52:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9909324</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>9</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9909324.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9909324</wfw:commentRss><description>&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;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Puzzles/default.aspx">Puzzles</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Dialogue/default.aspx">Dialogue</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/declaration+spaces/default.aspx">declaration spaces</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/scope/default.aspx">scope</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/customer+service/default.aspx">customer service</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Simple+Names/default.aspx">Simple Names</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/maui/default.aspx">maui</category></item><item><title>Simple names are not so simple</title><link>http://blogs.msdn.com/ericlippert/archive/2009/11/02/simple-names-are-not-so-simple.aspx</link><pubDate>Mon, 02 Nov 2009 14:23:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9909292</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>14</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9909292.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9909292</wfw:commentRss><description>&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;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Puzzles/default.aspx">Puzzles</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Language+Design/default.aspx">Language Design</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/declaration+spaces/default.aspx">declaration spaces</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/scope/default.aspx">scope</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Simple+Names/default.aspx">Simple Names</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/local+variables/default.aspx">local variables</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/refactoring/default.aspx">refactoring</category></item><item><title>I have a Fit, but a lack of Focus.</title><link>http://blogs.msdn.com/ericlippert/archive/2009/10/29/i-have-a-fit-but-a-lack-of-focus.aspx</link><pubDate>Thu, 29 Oct 2009 13:54:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9908258</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>17</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9908258.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9908258</wfw:commentRss><description>&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;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/myths/default.aspx">myths</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/reference+equality/default.aspx">reference equality</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Honda+fit/default.aspx">Honda fit</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Ford+Focus/default.aspx">Ford Focus</category></item><item><title>Some new videos</title><link>http://blogs.msdn.com/ericlippert/archive/2009/10/26/some-new-videos.aspx</link><pubDate>Mon, 26 Oct 2009 13:17:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9911473</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9911473.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9911473</wfw:commentRss><description>&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;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Video/default.aspx">Video</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/default.aspx">Covariance and Contravariance</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_+4.0/default.aspx">C# 4.0</category></item><item><title>What is this thing you call "thread safe"?</title><link>http://blogs.msdn.com/ericlippert/archive/2009/10/19/what-is-this-thing-you-call-thread-safe.aspx</link><pubDate>Mon, 19 Oct 2009 13:50:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9906219</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>29</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9906219.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9906219</wfw:commentRss><description>&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;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Threading/default.aspx">Threading</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Immutability/default.aspx">Immutability</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Wikipedia/default.aspx">Wikipedia</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Michelle+Pfeiffer/default.aspx">Michelle Pfeiffer</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Begging+the+question/default.aspx">Begging the question</category></item><item><title>As Timeless As Infinity</title><link>http://blogs.msdn.com/ericlippert/archive/2009/10/15/as-timeless-as-infinity.aspx</link><pubDate>Thu, 15 Oct 2009 13:25:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9904452</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>32</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9904452.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9904452</wfw:commentRss><description>&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;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/VBScript/default.aspx">VBScript</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Floating+Point+Arithmetic/default.aspx">Floating Point Arithmetic</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Dialogue/default.aspx">Dialogue</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Language+Design/default.aspx">Language Design</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/exception+handling/default.aspx">exception handling</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Delphi/default.aspx">Delphi</category></item></channel></rss>