CSharpFeeds - All your C# feeds in one place.

Sponsors

Feed: Fabulous Adventures In Coding

Site: http://blogs.msdn.com/b/ericlippert/ Link: http://blogs.msdn.com/ericlippert/rss.xml

Thursday, December 29, 2011

Shadowcasting in C#, Part Six

by Eric Lippert via Fabulous Adventures In Coding on 12/29/2011 3:05:00 PM

OK, let's finish up this year and this series. We have an algorithm that can compute what cells in the zero octant are in view to a viewer at the origin when given a function that determines whether a given cell is opaque or transparent. It marks the visible points by calling an action with the visible cells. We would like that to work in any octant, and for the viewer at any point, not just the origin. We can solve the "viewer at any point" problem by imposing a coordinate transformation on th ...

[ read more ]

Tuesday, December 27, 2011

Shadowcasting in C#, Part Five

by Eric Lippert via Fabulous Adventures In Coding on 12/27/2011 6:05:00 PM

I hope you all had a pleasant Christmas and Boxing Day; we chose to not travel to see family this year and had a delightful time visiting friends. We'll finish up 2011 here with a bit more on shadowcasting, and then pick up with more C# language design facts and opinions in January. OK, so we've found the top and bottom cells in a particular column portion, bounded by a top and bottom vector. Now we have two tasks. First, all cells in that portion that are in the radius need to be marked as v ...

[ read more ]

Thursday, December 22, 2011

Shadowcasting in C#, Part Four

by Eric Lippert via Fabulous Adventures In Coding on 12/22/2011 5:18:00 PM

Last time we saw how many different ways there were to get the calculation of the top cell based on the top vector wrong. Today we'll take a briefer look at determining the bottom cell. We know from our discussion of last time that the right way to determine what is the top-most visible cell in a column portion is to consider where the top vector leaves the column. By similar logic, the right way to determine where the bottom-most cell is in a column portion is to look at where the bottom vecto ...

[ read more ]

Monday, December 19, 2011

Shadowcasting in C#, Part Three

by Eric Lippert via Fabulous Adventures In Coding on 12/19/2011 4:06:00 PM

Before we get started, thanks for all the great comments to the previous couple of posts. I'll be updating the algorithm to try to make even better-looking circles of light based on the comments. Like I said, there's a lot of subtleties to these algorithms and I am just learning about them myself. To that end, in today's episode I am going to spend the entire prolix article analyzing a single division operation. You have been warned. Before we begin though, some jargon. A cell which is invisibl ...

[ read more ]

Thursday, December 15, 2011

Shadowcasting in C#, Part Two

by Eric Lippert via Fabulous Adventures In Coding on 12/15/2011 4:43:00 PM

I hope the basic idea of the shadow casting algorithm is now clear. Let's start to implement the thing. There are two main concerns to deal with. The easy one is "what should the interface to the computation look like?" The second is "how to implement it?" Let's deal with the easy one first; let's design the API. What does the caller need to provide? The coordinates of a central point The radius of the field of view Some way for the algorithm to know which cells are opaque What does the imp ...

[ read more ]

Monday, December 12, 2011

Shadowcasting in C#, Part One

by Eric Lippert via Fabulous Adventures In Coding on 12/12/2011 3:13:00 PM

I've always loved the "roguelike" games; perhaps you've played some of them. Those are the games where you get a top-down view of a tile-based world, and have as much real time as you like to make a choice of action. The canonical plot is to enter a dungeon, get to the bottom, retrieve the Amulet of Yendor, and make it back out of the dungeon with it. As you might expect, the original game with these characteristics was called "Rogue", and it has spawned many far more complex imitators. I'm par ...

[ read more ]

Thursday, December 08, 2011

So many interfaces, part two

by Eric Lippert via Fabulous Adventures In Coding on 12/8/2011 3:51:00 PM

In my earlier article from April 2011 on interface implementation I noted that C# supports a seldom-used feature called "interface re-implementation". This feature is useful when you need it but unfortunately is one of those features that can bite you if you use it incorrectly or accidentally. Every interface method of every interface you implement in a class or struct has to be "mapped" to a method in the type (either a method directly implemented by the type or a method that the type obtained ...

[ read more ]

Wednesday, October 19, 2011

The Roslyn Preview Is Now Available

by Eric Lippert via Fabulous Adventures In Coding on 10/19/2011 9:00:00 PM

I am super excited to announce that the Roslyn project code is now sufficiently coherent that we can start showing it to customers! But I am getting ahead of myself somewhat. What is this "Roslyn" project? Here's the deal. We've got these great premiere languages for .NET development, C# and Visual Basic. Obviously the compilers need to do considerable lexical, syntactic and semantic analysis of the code in order to first off, produce IL out the back end of the compiler, and second, produce all ...

[ read more ]

Monday, September 19, 2011

Inheritance and Representation

by Eric Lippert via Fabulous Adventures In Coding on 9/19/2011 5:18:00 PM

(Note: Not to be confused with Representation and Identity) Here's a question I got this morning: class Alpha<X>   where X : class {}class Bravo<T, U>   where T : class   where U : T {  Alpha<U> alpha;} This gives a compilation error stating that U cannot be used as a type argument for Alpha's type parameter X because U is not known to be a reference type. But surely U is known to be a reference type because U is constrained to be T, and T is constrained to ...

[ read more ]

Wednesday, September 07, 2011

What is this thing you call a "type"? Part Two

by Eric Lippert via Fabulous Adventures In Coding on 9/7/2011 5:58:00 PM

Well that was entirely predictable; as I said last time, if you ask ten developers for a definition of "type", you get ten different answers. The comments to the previous article make for fascinating reading! Here's my attempt at describing what "type" means to me as a compiler writer. I want to start by considering just the question of what a type is and not confuse that with how it is used. Fundamentally, a type in C# is a mathematical entity that obeys certain algebraic rules, just as natura ...

[ read more ]

Monday, August 29, 2011

What is this thing you call a "type"? Part one

by Eric Lippert via Fabulous Adventures In Coding on 8/29/2011 2:33:00 PM

(Eric is out camping; this posting is prerecorded. I'll be back in the office after Labour Day.) The word "type" appears almost five thousand times in the C# 4 specification, and there is an entire chapter, chapter 4, dedicated to nothing but describing types. We start the specification by noting that C# is "type safe" and has "a unified type system" (*). We say that programs "declare" types, and that declared types can be organized by namespace. Clearly types are incredibly important to the de ...

[ read more ]

Tuesday, July 19, 2011

Strings, immutability and persistence

by Eric Lippert via Fabulous Adventures In Coding on 7/19/2011 9:16:37 PM

Todays post is based on a question from StackOverflow; I liked it so much I figured hey, let's just blog it today. When you look at a string in C#, it looks to you like a collection of characters, end of story. But of course, behind the scenes there is a data structure in memory somewhere to implement that collection of characters. In the .NET CLR, strings are laid out in memory pretty much the same way that BSTRs were implemented in OLE Automation: as a word-aligned memory buffer consisting of ...

[ read more ]

Tuesday, July 12, 2011

What curious property does this string have?

by Eric Lippert via Fabulous Adventures In Coding on 7/12/2011 7:19:00 PM

There are all kinds of interesting things in the Unicode standard. For example, the block of characters from U+A000 to U+A48F is for representing syllables in the "Yi script". Apparently it is a Chinese language writing system developed during the Tang Dynasty. A string drawn from this block has an unusual property; the string consists of just two characters, both the same: a repetition of character U+A0A2: string s = "??"; Or, if your browser can't hack the Yi script, that's the equivalent of ...

[ read more ]

Friday, July 08, 2011

My Buddy Neil Totally Agrees With Me

by Eric Lippert via Fabulous Adventures In Coding on 7/8/2011 4:24:51 PM

[No computer stuff today; just some fun for a Friday.] British fantasy author Neil Gaiman was in Seattle recently. I was so disappointed that I did not find out about it until it was too late to attend his event. It's a pity I missed it because I've been wanting for years to ask Neil Gaiman if he likes soup. To explain why, we'll have to go back to 1993. Remember 1993? The first wave of HTTP-based document servers were going up on the internet; it was the beginning of the internet as we know ...

[ read more ]

Thursday, June 23, 2011

Ref returns and ref locals

by Eric Lippert via Fabulous Adventures In Coding on 6/23/2011 2:01:00 PM

"Ref returns" are the subject of another great question from StackOverflow that I thought I might share with a larger audience. Ever since C# 1.0 you've been able to create an "alias" to a variable by passing a "ref to a variable" to certain methods: static void M(ref int x){    x = 123;}...int y = 456;M(ref y); Despite their different names, "x" and "y" are now aliases for each other; they both refer to the same storage location. When x is changed, y changes too because they are ...

[ read more ]

Thursday, June 16, 2011

Atomicity, volatility and immutability are different, part three

by Eric Lippert via Fabulous Adventures In Coding on 6/16/2011 2:03:00 PM

So what does "volatile" mean, anyway? Misinformation abounds on this subject. First off, so as to not bury the lead: in C# the rules have been carefully designed so that every volatile field read and write is also atomic. (Of course the converse does not follow; it is perfectly legal for an operation to be atomic without it being "volatile", whatever that means.) The way this is achieved is simple; the rules of C# only permit you to annotate fields with "volatile" if the field also has a type ...

[ read more ]

Tuesday, May 31, 2011

Atomicity, volatility and immutability are different, part two

by Eric Lippert via Fabulous Adventures In Coding on 5/31/2011 9:56:24 PM

Last time we established that an "atomic" read or write of a variable means that in multithreaded scenarios, you never end up with "halfway mutated" values in the variable. The variable goes from unmutated to mutated directly, with no intervening state. I also talked a bit about how making fields of a struct "readonly" has no effect on atomicity; when the struct is copied around, it may be copied around four bytes at a time regardless of whether its fields are marked as "readonly" or not. There ...

[ read more ]

Monday, May 23, 2011

Read-only and threadsafe are different

by Eric Lippert via Fabulous Adventures In Coding on 5/23/2011 2:47:00 PM

Here's a common problem that we face in the compiler realm all the time: you want to make an efficient immutable lookup table for mapping names to "symbols". This is in a sense the primary problem that the compiler has to solve; someone says "x = y + z;" and we have to figure out what "x", "y" and "z" mean before we can do any more analysis. An obvious way to do that is to figure out all the name-to-symbol mappings for a particular declaration space once, ahead of time, stuff the results into a ...

[ read more ]

Thursday, May 19, 2011

Optional argument corner cases, part four

by Eric Lippert via Fabulous Adventures In Coding on 5/19/2011 3:19:00 PM

(This is the fourth and final part of a series on the corner cases of optional arguments in C# 4; part three is here.) Last time we discussed how some people think that an optional argument generates a bunch of overloads that call each other. People also sometimes incorrectly think that void M(string format, bool b = false) {   Console.WriteLine(format, b); } is actually a syntactic sugar for something morally like: void M(string format, bool? b){  bool realB = b ?? false;  Cons ...

[ read more ]

Monday, May 16, 2011

Optional argument corner cases, part three

by Eric Lippert via Fabulous Adventures In Coding on 5/16/2011 2:50:00 PM

(This is part three of a series on the corner cases of optional arguments in C# 4; part two is here. Part four is here.) A lot of people seem to think that this: void M(string x, bool y = false) { ... whatever ... } is actually a syntactic sugar for the way you used to have to write this in C#, which is: void M(string x) { M(x, false); }void M(string x, bool y) { ... whatever ... } But it is not. The syntactic sugar here is not on the declaration side, but rather on the call side. There is only ...

[ read more ]

Thursday, May 12, 2011

Optional argument corner cases, part two

by Eric Lippert via Fabulous Adventures In Coding on 5/12/2011 4:29:35 PM

(This is part two of a series on the corner cases of optional arguments in C# 4. Part one is here. Part three is here. This portion of the series was inspired by this StackOverflow question.) Last time we saw that the declared optional arguments of an interface method need not be optional arguments of an implementing class method. That seems potentially confusing; why not require that an implementing method on a class exactly repeat the optional arguments of the declaration? Because the cure is ...

[ read more ]

Monday, May 09, 2011

Optional argument corner cases, part one

by Eric Lippert via Fabulous Adventures In Coding on 5/9/2011 2:29:00 PM

(This is part one of a series on the corner cases of optional arguments in C# 4. Part two is here.) In C# 4.0 we added "optional arguments"; that is, you can state in the declaration of a method's parameter that if certain arguments are omitted, then constants can be substituted for them: void M(int x = 123, int y = 456) { } can be called as M(), M(0) and M(0, 1). The first two cases are treated as though you'd said M(123, 456) and M(0, 456) respectively. This was a controversial feature for th ...

[ read more ]

Wednesday, April 20, 2011

Uses and misuses of implicit typing

by Eric Lippert via Fabulous Adventures In Coding on 4/20/2011 5:37:52 PM

One of the most controversial features we've ever added was implicitly typed local variables, aka "var". Even now, years later, I still see articles debating the pros and cons of the feature. I'm often asked what my opinion is, so here you go. Let's first establish what the purpose of code is in the first place. For this article, the purpose of code is to create value by solving a business problem. Now, sure, that's not the purpose of all code. The purpose of the assembler I wrote for my CS 24 ...

[ read more ]

Wednesday, April 13, 2011

Refreshing the Async CTP

by Eric Lippert via Fabulous Adventures In Coding on 4/13/2011 4:00:00 PM

Good morning everyone! I am pleased to tell you that the C# and VB teams are announcing a "refresh" of the async Community Technology Preview at MIX11 today, and that it is as of right now available on the Async CTP site. Recall that the CTP release is an early look at our thinking for the proposed async language features so that we can get your feedback. Rather than posting feedback here, please let us know what you think on the Async Forum. We've gotten a lot of good feedback ...

[ read more ]

Monday, April 04, 2011

So many interfaces!

by Eric Lippert via Fabulous Adventures In Coding on 4/4/2011 3:14:57 PM

Today, another question from StackOverflow, and again, presented as a dialogue as is my wont. The MSDN documentation for List<T> says that the class is declared as public class List<T> : IList<T>, ICollection<T>, IEnumerable<T>,                        IList, ICollection, IEnumerable Does List<T> really implement all those interfaces? Yes. Why so m ...

[ read more ]

Friday, April 01, 2011

Compound Assignment, Part Two

by Eric Lippert via Fabulous Adventures In Coding on 4/1/2011 8:06:00 AM

Last time I discussed how the compound assignment operators of the form “x op= y” have some perhaps unobvious behaviours in C#, namely: (1) though logically this is expanded as “x = x op y”, x is only evaluated once(2) for built-in operators, if necessary, a cast is inserted, so that this is analyzed as “x = (T)(x op y)” (3) for built-in operators, if “x = y” would be illegal then so is “x op= y” I am pleased to announce that we are at ...

[ read more ]

Tuesday, March 29, 2011

Compound Assignment, Part One

by Eric Lippert via Fabulous Adventures In Coding on 3/29/2011 1:24:00 PM

When people try to explain the compound assignment operators += –= *= /= %= <<= >>= &= |= ^= to new C# programmers they usually say something like “x += 10; is just a short way of writing x = x + 10;”. Now, though that is undoubtedly true for a local variable x of type int, that’s not the whole story, not by far. There are actually many subtle details to the compound assignment operators that you might not appreciate at first glance. First off, suppose the expression on the lef ...

[ read more ]

Thursday, March 24, 2011

Implementing the virtual method pattern in C#, Part Three

by Eric Lippert via Fabulous Adventures In Coding on 3/24/2011 2:10:00 PM

Last time we saw how you could emulate virtual methods in a language that only had static methods by creating fields of delegate type, and then choosing what delegates go into the fields. However, this is not very space-efficient. Suppose there were a hundred virtual methods on Animal instead of two. That means that every class derived from Animal has a hundred fields, and in most of them, those fields are exactly the same, all the time. You make three hundred giraffes and each one of them will ...

[ read more ]

Monday, March 21, 2011

Implementing the virtual method pattern in C#, Part Two

by Eric Lippert via Fabulous Adventures In Coding on 3/21/2011 2:08:00 PM

So far we've gotten rid of instance methods; they're just static methods that take a hidden "this" parameter. But virtual methods are a bit harder. We're going to implement virtual methods as fields of delegate type containing delegates to static methods. abstract class Animal{  public Func<Animal, string> Complain;  public Func<Animal, string> MakeNoise;  public static string MakeNoise(Animal _this)  {    return "";  }} OK, everything seems f ...

[ read more ]

Thursday, March 17, 2011

Implementing the virtual method pattern in C#, Part One

by Eric Lippert via Fabulous Adventures In Coding on 3/17/2011 1:42:00 PM

If you've been in this business for any length of time you've undoubtedly seen some of the vast literature on "design patterns" -- you know, those standard solutions to common problems with names like "factory" and "observer" and "singleton" and "iterator" and "composite" and "adaptor" and "decorator" and... and so on. It is frequently useful to be able to take advantage of the analysis and design skills of others who have already given considerable thought to codifying patterns that solve comm ...

[ read more ]

Monday, March 14, 2011

To box or not to box, that is the question

by Eric Lippert via Fabulous Adventures In Coding on 3/14/2011 2:20:00 PM

Suppose you have an immutable value type that is also disposable. Perhaps it represents some sort of handle. struct MyHandle : IDisposable{    public MyHandle(int handle) : this() { this.Handle = handle; }    public int Handle { get; private set; }    public void Dispose()    {        Somehow.Close(this.Handle);    }} You might think hey, you know, I'll decrease my probability of clos ...

[ read more ]

Thursday, March 10, 2011

References and Pointers, Part Two

by Eric Lippert via Fabulous Adventures In Coding on 3/10/2011 5:50:00 PM

Here's a handy type I whipped up when I was translating some complex pointer-manipulation code from C to C#. It lets you make a safe "managed pointer" to the interior of an array. You get all the operations you can do on an unmanaged pointer: you can dereference it as an offset into an array, do addition and subtraction, compare two pointers for equality or inequality, and represent a null pointer. But unlike the corresponding unsafe code, this code doesn't mess up the garbage collector and wil ...

[ read more ]

Monday, March 07, 2011

References and Pointers, Part One

by Eric Lippert via Fabulous Adventures In Coding on 3/7/2011 5:50:35 PM

Writing code in C# is really all about the programmatic manipulation of values. A value is either of a value type, like an integer or a decimal, or it's a reference to an instance of a reference type, like a string or an exception. Values you manipulate always have a storage location that stores the value; those storage locations are called "variables". Often in a C# program you manipulate the values by describing which variable you're interested in. In C# there are three basic operations you ...

[ read more ]

Thursday, March 03, 2011

Danger, Will Robinson!

by Eric Lippert via Fabulous Adventures In Coding on 3/3/2011 6:41:00 PM

As long-time readers of this blog know, I am often asked why a particular hunk of bad-smelling code does not produce a compiler warning. "Why not?" questions are inherently hard to answer because they turn causation on its head; normally we ask what caused a particular thing to happen, not what caused a particular thing to not happen. Therefore, rather than attack that question directly I like to rephrase the question into questions about the proposed feature. (A warning is of course a feature ...

[ read more ]

Monday, February 28, 2011

Guidelines and rules for GetHashCode

by Eric Lippert via Fabulous Adventures In Coding on 2/28/2011 2:39:00 PM

"The code is more what you'd call guidelines than actual rules" - truer words were never spoken. It's important when writing code to understand what are vague "guidelines" that should be followed but can be broken or fudged, and what are crisp "rules" that have serious negative consequences for correctness and robustness. I often get questions about the rules and guidelines for GetHashCode, so I thought I might summarize them here. What is GetHashCode used for? It is by design useful for only ...

[ read more ]

Thursday, February 24, 2011

Never Say Never, Part Two

by Eric Lippert via Fabulous Adventures In Coding on 2/24/2011 2:31:00 PM

Whether we have a "never" return type or not, we need to be able to determine when the end point of a method is unreachable for error reporting in methods that have non-void return type. The compiler is pretty clever about working that out; it can handle situations like int M(){  try  {    while(true) N();  }  catch(Exception ex)   {     throw new WrappingException(ex);   }} The compiler knows that N either throws or it doesn't, and ...

[ read more ]

Monday, February 21, 2011

Never Say Never, Part One

by Eric Lippert via Fabulous Adventures In Coding on 2/21/2011 2:59:00 PM

Can you find a lambda expression that can be implicitly converted to Func<T> for any possible T? . . . . . . . . . . . Hint: The same lambda is convertible to Action as well. . . . . . . . . . Func<int> function = () => { throw new Exception(); }; The rule for assigning lambdas to delegates that return int is not "the body must return an int". Rather, the rules are: * All returns in the block must return an expression convertible to int.* The end point of the block must not be re ...

[ read more ]

Thursday, February 17, 2011

Looking inside a double

by Eric Lippert via Fabulous Adventures In Coding on 2/17/2011 2:36:00 PM

Occasionally when I'm debugging the compiler or responding to a user question I'll need to quickly take apart the bits of a double-precision floating point number. Doing so is a bit of a pain, so I've whipped up some quick code that takes a double and tells you all the salient facts about it. I present it here, should you have any use for it yourself. (Note that this code was built for comfort, not speed; it is more than fast enough for my purposes so I've spent zero time optimizing it.) To und ...

[ read more ]

Monday, February 14, 2011

What would Feynman do?

by Eric Lippert via Fabulous Adventures In Coding on 2/14/2011 2:29:00 PM

No one I know at Microsoft asks those godawful "lateral-thinking puzzle" interview questions anymore. Maybe someone still does, I don't know. But rumour has it that a lot of companies are still following the Microsoft lead from the 1990s in their interviews. In that tradition, I present a sequel to Keith Michaels' 2003 exercise in counterfactual reasoning. Once more, we dare to ask the question "how well would the late Nobel-Prize-winning physicist Dr. Richard P. Feynman do in a technical inter ...

[ read more ]

Thursday, February 10, 2011

Optional arguments on both ends

by Eric Lippert via Fabulous Adventures In Coding on 2/10/2011 2:54:00 PM

Before we get into today's topic, a quick update on my posting from last year about Roslyn jobs. We have gotten a lot of good leads and made some hires but we still have positions open, both on the Roslyn team and on the larger Visual Studio team. For details, see this post on the Visual Studio blog. Again, please do not send me resumes directly; send them via the usual career site. Thanks! Here's a recent question I got from a reader: what is the correct analysis of this little problem i ...

[ read more ]

Monday, February 07, 2011

Strange, but legal

by Eric Lippert via Fabulous Adventures In Coding on 2/7/2011 2:51:00 PM

"Can a property or method really be marked as both abstract and override?" one of my coworkers just asked me. My initial gut response was "of course not!" but as it turns out, the Roslyn codebase itself has a property getter marked as both abstract and override. (Which is why they were asking in the first place.) I thought about it a bit more and reconsidered. This pattern is quite rare, but it is perfectly legal and even sensible. The way it came about in our codebase is that we have a large, ...

[ read more ]

Thursday, February 03, 2011

Curiouser and curiouser

by Eric Lippert via Fabulous Adventures In Coding on 2/3/2011 2:55:00 PM

Here's a pattern you see all the time in C#: class Frob : IComparable<Frob> At first glance you might ask yourself why this is not a "circular" definition; after all, you're not allowed to say "class Frob : Frob"(*). However, upon deeper reflection that makes perfect sense; a Frob is something that can be compared to another Frob. There's not actually a real circularity there. This pattern can be genericized further: class SortedList<T> where T : IComparable<T> Again, it might ...

[ read more ]

Monday, January 31, 2011

Spot the defect: Bad comparisons, part four

by Eric Lippert via Fabulous Adventures In Coding on 1/31/2011 2:44:00 PM

One more easy one. I want to "sort" a list into a random, shuffled order. I can do that by simply randomizing whether any two elements are greater than, less than, or equal to each other: myList.Sort((x, y) => (new Random()).Next(-1, 2)); That generates a random -1, 0 or 1 for every comparison, right? So it will sort the list into random order, right? . . . . . . . There are multiple defects here. First off, clearly this violates all our rules for comparison functions. It does not produce a ...

[ read more ]

Thursday, January 27, 2011

Spot the defect: Bad comparisons, part three

by Eric Lippert via Fabulous Adventures In Coding on 1/27/2011 2:56:00 PM

Did you notice how last time my length comparison on strings was unnecessarily verbose? I could have written it like this: static int ByLength(string x, string y){  if (x == null && y == null) return 0:  if (x == null) return -1;  if (y == null) return 1;  return CompareInts(x.Length, y.Length);}static int CompareInts(int x, int y){  // Positive if x is larger, negative if y is larger, zero if equal  return x - y; } static Comparison<T> ThenBy<T&g ...

[ read more ]

Monday, January 24, 2011

Spot the defect: Bad comparisons, part two

by Eric Lippert via Fabulous Adventures In Coding on 1/24/2011 2:43:00 PM

Suppose I want to sort a bunch of strings into order first by length, and then, once they are sorted by length, sort each group that is the same length by some other comparison. We can easily build such a device with higher-order programming: static Comparison<string> FirstByLength(Comparison<string> thenBy){  return (string x, string y) =>  {    // Null strings are sorted before zero-length strings; remember, we need to provide a total ordering. &nb ...

[ read more ]

Thursday, January 20, 2011

Spot the defect: Bad comparisons, part one

by Eric Lippert via Fabulous Adventures In Coding on 1/20/2011 2:16:00 PM

The mutable List<T> class provides an in-place sort method which can take a comparison delegate. It's quite handy to be able to sort a list into order by being able to compare any two elements, but you have to make sure you get it right. First off, what are the requirements of the comparison delegate? They are clearly documented: the comparison takes two elements and returns a 32 bit signed integer. If the first element is greater than the second then the integer is greater than zero. If ...

[ read more ]

Monday, January 17, 2011

Not as easy as it looks, Part Two

by Eric Lippert via Fabulous Adventures In Coding on 1/17/2011 7:25:00 PM

Holy goodness, did you guys ever find a lot of additional ways in which an "eliminate variable" refactoring can go wrong. Just a few of your observations: (again, in every case, "x" is eliminated.) Any situation in which x is being treated as a variable rather than a value will pose a problem. Some obvious ones, like if x is on the left side of an assignment, or the target of a ++, or used as a "ref" or "out" parameter are straightforward. But there are some situations in which it is a bit surp ...

[ read more ]

Thursday, January 13, 2011

Not as easy as it looks

by Eric Lippert via Fabulous Adventures In Coding on 1/13/2011 3:01:00 PM

My colleague Kevin works on (among many other things) the refactoring engine in the C# IDE. He and I were at the end of last year discussing the possible cases for a hypothetical "eliminate variable" refactoring. I thought that it might be of interest to you guys to get a glimpse of the sorts of issues that the IDE team faces on a daily basis. First off, what is the "eliminate variable" refactoring? It is seemingly straightforward, but as we'll see, appearances can be deceiving. Suppose you hav ...

[ read more ]

Monday, December 20, 2010

Why are anonymous types generic?

by Eric Lippert via Fabulous Adventures In Coding on 12/20/2010 2:30:00 PM

Suppose you use an anonymous type in C#: var x = new { A = "hello", B = 123.456 }; Ever taken a look at what code is generated for that thing? If you crack open the assembly with ILDASM or some other tool, you'll see this mess in the top-level type definitions .class '<>f__AnonymousType0`2'<'<A>j__TPar','<B>j__TPar'> What the heck? Let's clean that up a bit. We've mangled the names so that you are guaranteed that you cannot possibly accidentally use this thing "as is" fr ...

[ read more ]

Monday, December 13, 2010

All your base do not belong to you

by Eric Lippert via Fabulous Adventures In Coding on 12/13/2010 3:00:00 PM

People sometimes ask me why you can’t do this in C#: class GrandBase{  public virtual void M() { Console.WriteLine("GB"); }}class Base : GrandBase{  public override void M() { Console.WriteLine("B"); }}class Derived : Base{  public override void M()   {     Console.WriteLine("D");    base.base.M(); // illegal!   }} The author of the most-derived class here wishes to call its GrandBase implementation of M, rather than the Base implementation ...

[ read more ]

Monday, November 29, 2010

Bit twiddling: What does warning CS0675 mean?

by Eric Lippert via Fabulous Adventures In Coding on 11/29/2010 6:16:30 PM

From the sublime level of continuation passing style we go back to the mundane level of twiddling individual bits. int i = SomeBagOfBits();ulong u = SomeOtherBagOfBits();ulong result = u | i; // combine them together Whoops, that's an error. "Operator | cannot be applied to operands of type int and ulong." There are bitwise-or operators defined on int, uint, long and ulong, but none between int and ulong. You cannot use the int version because the ulong might not fit, and you cannot use the ulo ...

[ read more ]

Tuesday, November 23, 2010

Asynchrony in C# 5, Part Eight: More Exceptions

by Eric Lippert via Fabulous Adventures In Coding on 11/23/2010 2:31:00 PM

(In this post I'll be talking about exogenous, vexing, boneheaded and fatal exceptions. See this post for a definition of those terms.) If your process experiences an unhandled exception then clearly something bad and unanticipated has happened. If its a fatal exception then you're already in no position to save the process; it is going down. You might as well leave it unhandled, or just log it and rethrow it. If it had been anticipated because it's a vexing or exogenous exception then there wo ...

[ read more ]

Friday, November 19, 2010

Asynchrony in C# 5, Part Seven: Exceptions

by Eric Lippert via Fabulous Adventures In Coding on 11/19/2010 4:47:53 PM

Resuming where we left off (ha ha ha!) after that brief interruption: exception handling in "resumable" methods like our coroutine-like asynchronous methods is more than a little bit weird. To get a sense of how weird it is, you might want to first refresh your memory of my recent series on the design of iterator blocks, particularly the post about the difference between a "push" model and a "pull" model. Briefly though: In a regular code block, a try block surrounding a normal "synchronous" ca ...

[ read more ]

Monday, November 15, 2010

The Annotated Fourth Edition is available

by Eric Lippert via Fabulous Adventures In Coding on 11/15/2010 2:45:00 PM

A brief digression from C# 5 to talk about C# 4: the annotated C# 4 specification is now available in book form from Addison-Wesley. It is of course handy to have a specification in book form, particularly if you're going to while away the hours with the book sitting by a warm fire. (It's hundreds of pages long; you can keep a fire going for hours.) But the real value-add of this edition over the downloadable version is that the print version is heavily annotated by numerous people who know a t ...

[ read more ]

Thursday, November 11, 2010

Asynchrony in C# 5 Part Six: Whither async?

by Eric Lippert via Fabulous Adventures In Coding on 11/11/2010 2:54:00 PM

A number of people have asked me what motivates the design decision to require any method that contains an "await" expression to be prefixed with the contextual keyword "async". Like any design decision there are pros and cons here that have to be evaluated in the context of many different competing and incompossible principles. There's not going to be a slam-dunk solution here that meets every criterion or delights everyone. We're always looking for an attainable compromise, not for unattaina ...

[ read more ]

Monday, November 08, 2010

Asynchrony in C# 5 Part Five: Too many tasks

by Eric Lippert via Fabulous Adventures In Coding on 11/8/2010 2:26:00 PM

Suppose a city has a whole bunch of bank branches, each of which has a whole bunch of tellers and one gofer. There are a whole bunch of customers in the city, each of whom wants to withdraw a whole bunch of money from the bank at some varying time throughout the day. The algorithm goes like this: A customer finds the nearest bank branch and evaluates its line. If the line is out the door, then the customer goes to another bank branch. This continues until they either find one with a short enoug ...

[ read more ]

Thursday, November 04, 2010

Asynchrony in C# 5.0 part Four: It's not magic

by Eric Lippert via Fabulous Adventures In Coding on 11/4/2010 1:23:00 PM

Today I want to talk about asynchrony that does not involve any multithreading whatsoever. People keep on asking me "but how is it possible to have asynchrony without multithreading?" A strange question to ask because you probably already know the answer. Let me turn the question around: how is it possible to have multitasking without multiple CPUs? You can't do two things "at the same time" if there's only one thing doing the work! But you already know the answer to that: multitasking on a si ...

[ read more ]

Monday, November 01, 2010

Asynchrony in C# 5, Part Three: Composition

by Eric Lippert via Fabulous Adventures In Coding on 11/1/2010 1:34:00 PM

I was walking to my bus the other morning at about 6:45 AM. Just as I was about to turn onto 45th street, a young man, shirtless, covered in blood ran down 45th at considerable speed right in front of me. Behind him was another fellow, wielding a baseball bat. My initial thought was "holy goodness, I have to call the police right now!" Then I saw that the guy with the baseball bat was himself being chased by Count Dracula, a small horde of zombies, a band of pirates, one medieval knight, and b ...

[ read more ]

Asynchrony in C# 5, Part Three: Composition

by Eric Lippert via Fabulous Adventures In Coding on 11/1/2010 1:34:00 PM

I was walking to my bus the other morning at about 6:45 AM. Just as I was about to turn onto 45th street, a young man, shirtless, covered in blood ran down 45th at considerable speed right in front of me. Behind him was another fellow, wielding a baseball bat. My initial thought was "holy goodness, I have to call the police right now!" Then I saw that the guy with the baseball bat was himself being chased by Count Dracula, a small horde of zombies, a band of pirates, one medieval knight, and b ...

[ read more ]

Friday, October 29, 2010

Asynchronous Programming in C# 5.0 part two: Whence await?

by Eric Lippert via Fabulous Adventures In Coding on 10/29/2010 1:44:00 PM

I want to start by being absolutely positively clear about two things, because our usability research has shown this to be confusing. Remember our little program from last time? async void ArchiveDocuments(List<Url> urls){  Task archive = null;  for(int i = 0; i < urls.Count; ++i)  {    var document = await FetchAsync(urls[i]);    if (archive != null)      await archive;    archive = ArchiveAsync(docu ...

[ read more ]

Thursday, October 28, 2010

Asynchrony in C# 5, Part One

by Eric Lippert via Fabulous Adventures In Coding on 10/28/2010 6:30:00 PM

The designers of C# 2.0 realized that writing iterator logic was painful. So they added iterator blocks. That way the compiler could figure out how to build a state machine that could store the continuation - the “what comes next” - in state somewhere, hidden behind the scenes, so that you don’t have to write that code. They also realized that writing little methods that make use of local variables was painful. So they added anonymous methods. That way the compiler could figure out how to hois ...

[ read more ]

Wednesday, October 27, 2010

Continuation Passing Style Revisited Part Five: CPS and Asynchrony

by Eric Lippert via Fabulous Adventures In Coding on 10/27/2010 1:45:00 PM

Today is when things are going to get really long and confusing. But we'll make it through somehow. Consider the following task: you’ve got a list of URLs. You want to fetch the document associated with each URL. (Let’s suppose for the sake of argument that this always succeeds.) You then want to make a copy of the document on your network attached tape drive storage, because you’re old school. Totally straightforward. Two lines of code. Hardly worth making a method out of: void ArchiveDocume ...

[ read more ]

Tuesday, October 26, 2010

Continuation Passing Style Revisited Part Four: Turning yourself inside out

by Eric Lippert via Fabulous Adventures In Coding on 10/26/2010 1:15:00 PM

The obvious question at this point is: if CPS is so awesome then why don’t we use it all the time? Why have most professional developers never heard of it, or, those who have, think of it as something only those crazy Scheme programmers do? First of all, it is simply hard for most people who are used to thinking about subroutines, loops, try-catch-finally and so on to reason about delegates being used for control flow in this way. I am reviewing my notes on CPS from CS442 right now and I see t ...

[ read more ]

Monday, October 25, 2010

Continuation Passing Style Revisited Part Three: Musings about coroutines

by Eric Lippert via Fabulous Adventures In Coding on 10/25/2010 1:40:00 PM

Last time I sketched briefly how one might implement interesting control flows like try-catch using continuations; as we saw, the actual implementations of Try and Throw are trivial once you have CPS. I'm sure that you could extend that work to implement try-catch-finally. Or, another basic exercise when learning about CPS you might try is to implement coroutines. What’s a coroutine? Excellent question! Cast your mind back to the days of cooperative multitasking in Windows 3. The idea of coop ...

[ read more ]

Continuation Passing Style Revisited Part Three: Musings about coroutines

by Eric Lippert via Fabulous Adventures In Coding on 10/25/2010 1:40:00 PM

Last time I sketched briefly how one might implement interesting control flows like try-catch using continuations; as we saw, the actual implementations of Try and Throw are trivial once you have CPS. I'm sure that you could extend that work to implement try-catch-finally. Or, another basic exercise when learning about CPS you might try is to implement coroutines. What’s a coroutine? Excellent question! Cast your mind back to the days of cooperative multitasking in Windows 3. The idea of coop ...

[ read more ]

Friday, October 22, 2010

Continuation Passing Style Revisited Part Two: Handwaving about control flow

by Eric Lippert via Fabulous Adventures In Coding on 10/22/2010 1:29:00 PM

Last time on Fabulous Adventures: “But we can construct arbitrarily complex control flows by keeping track of multiple continuations and deciding which one gets to go next.” Let’s look at an example of something more complex than a conditional. Consider a simplified version of “try-catch”, where there is no expression to the throw. A throw is simply a non-local goto that goes to the nearest enclosing catch. The traditional way to think about void Q(){  try   {     B(A ...

[ read more ]

Thursday, October 21, 2010

Continuation Passing Style Revisited, Part One

by Eric Lippert via Fabulous Adventures In Coding on 10/21/2010 1:38:00 PM

Good morning fabulous readers, let me just start by saying that this is going to get really long and really complicated but it will all pay off in the end. I’m also going to be posting on an accelerated schedule, more than my usual two posts per week. (It’ll eventually become clear why I'm doing all of this, he said mysteriously. Remember, suspense is a sign of a quality blog.) I want to talk quite a bit about a subject that I first discussed briefly a few years back, namely, Continuation Pass ...

[ read more ]

Monday, October 11, 2010

Debunking another myth about value types

by Eric Lippert via Fabulous Adventures In Coding on 10/11/2010 3:53:00 PM

Here's another myth about value types that I sometimes hear: "Obviously, using the new operator on a reference type allocates memory on the heap. But a value type is called a value type because it stores its own value, not a reference to its value. Therefore, using the new operator on a value type allocates no additional memory. Rather, the memory already allocated for the value is used." That seems plausible, right? Suppose you have an assignment to, say, a field s of type S: s = new S(123, 45 ...

[ read more ]

Thursday, October 07, 2010

No Backtracking, Part Two

by Eric Lippert via Fabulous Adventures In Coding on 10/7/2010 5:12:00 PM

As i was saying last time, the nice thing about "no backtracking" is that it makes the language much easier to understand. Simple rules benefit both the compiler and the code reader; both are attempting to read the code to make sense of it. It is not always a good idea to take advantage of the compiler's ability to search a large space if that makes it harder for a human to understand the code. Suppose you have something like this mess: (*) namespace XYZ.DEF{      public cla ...

[ read more ]

Monday, October 04, 2010

No backtracking, Part One

by Eric Lippert via Fabulous Adventures In Coding on 10/4/2010 4:56:00 PM

A number of the articles I’ve published over the years involve “backtracking” algorithms; most recently my series on how to solve Sudoku puzzles (and more generally, all graph colouring problems) by backtracking. The idea of a backtracking algorithm is really simple and powerful: when faced with a choice, try every possibility. If all of them go wrong, backtrack to the previous choice and try a different possibility. Backtracking algorithms are essentially a depth-first search of the space of p ...

[ read more ]

Thursday, September 09, 2010

Old school tree display

by Eric Lippert via Fabulous Adventures In Coding on 9/9/2010 1:58:00 PM

I'm back from my various travels, refreshed and ready for more fabulous adventures in coding. A while back I did a coding challenge for you all: to turn a sequence of strings into a fancy comma-separated list. You might also recall that I did a bit on how to generate all possible arbitrary trees, which I notated with a simple bracing format. Today, let's combine those two problems. What I want to do is create a function which takes an arbitrary tree where each node has some string data, and tu ...

[ read more ]

Thursday, July 29, 2010

Graph Colouring, Part Five

by Eric Lippert via Fabulous Adventures In Coding on 7/29/2010 1:40:00 PM

I said last time that I was interested in finding colourings for graphs that have lots of fully connected subgraphs, aka "cliques". For instance, I'd like to find a four-colouring for this sixteen-node graph: Yuck. What a mess. What this graph is doing a bad job of conveying is that there are twelve fully connected subsets. {0, 1, 2, 3} forms a clique. So does {0, 1, 4, 5}. And so does {0, 4, 8, 12}. It would be great if I had a better way to display full connectedness. How about this: I'll j ...

[ read more ]

Monday, July 26, 2010

Graph Colouring, Part Four

by Eric Lippert via Fabulous Adventures In Coding on 7/26/2010 3:20:00 PM

Let's give it a try. Can we colour South America with only four colours? Let's start by stating what all the edges are in the graph of South America: const int Brazil = 0;const int FrenchGuiana = 1;const int Suriname = 2;const int Guyana = 3; const int Venezuala = 4;const int Colombia = 5;const int Ecuador = 6;const int Peru = 7;const int Chile = 8;const int Bolivia = 9;const int Paraguay = 10;const int Uruguay = 11;const int Argentina = 12;var SA = new Dictionary<int, int[]>(){ &nb ...

[ read more ]

Thursday, July 22, 2010

Graph Colouring with Simple Backtracking, Part Three

by Eric Lippert via Fabulous Adventures In Coding on 7/22/2010 1:54:00 PM

OK, we've got our basic data structures in place. Graph colouring is a very well-studied problem. It's known to be NP-complete for arbitrary graphs, so (assuming that P!=NP) we're not going to find an always-fast algorithm for colouring an arbitrary graph. However, for typical graphs that we encounter in the wild, the following simple algorithm is pretty good. Start by saying that every node can be every possible colour. Then: 1) Do you have a single possible colouring for every node in t ...

[ read more ]

Thursday, July 15, 2010

Graph Colouring With Simple Backtracking, Part Two

by Eric Lippert via Fabulous Adventures In Coding on 7/15/2010 3:09:00 PM

Before I begin a quick note: congratulations and best wishes to David Johnson, currently the president of my alma mater, the University of Waterloo. The Queen has appointed him to be the next Governor General of Canada come this October. For those of you unfamiliar with the Canadian political structure, Queen Elizabeth is the sovereign ruler Canada; the Governor General acts as her direct representative in Canada and therefore has the (mostly ceremonial, but some real) powers of a head of state ...

[ read more ]

Monday, July 12, 2010

Graph Colouring With Simple Backtracking, Part One

by Eric Lippert via Fabulous Adventures In Coding on 7/12/2010 3:15:00 PM

As regular readers know, I'm interested in learning how to change my C# programming style to emphasize more concepts from functional programming, like use of immutable rather than mutable data structures and use of declarative control flow like LINQ queries instead of imperative control flow in the form of loops. I thought I'd solve a fairly straightforward problem using a mix of immutable and mutable, declarative and imperative styles to indicate when each is useful and appropriate. I pic ...

[ read more ]

Monday, June 28, 2010

Computing a Cartesian Product with LINQ

by Eric Lippert via Fabulous Adventures In Coding on 6/28/2010 3:06:00 PM

And here we have yet another post inspired by a question on StackOverflow: how do you compute the Cartesian product of arbitrarily many sequences using LINQ? UPDATE: Ian Griffiths has an interesting series of articles that approaches this question in considerably more depth than I do; check it out! First off, let's make sure that we know what we're talking about. I'll notate sequences as ordered sets {a, b, c, d,...}. The Cartesian product of two sequences S1 and S2 is the sequence of all possi ...

[ read more ]

Monday, June 14, 2010

Hide and seek

by Eric Lippert via Fabulous Adventures In Coding on 6/14/2010 3:40:00 PM

Another interesting question from StackOverflow. That thing is a gold mine for blog topics. Consider the following: class B{  public int X() { return 123; }}class D : B{  new protected int X() { return 456; }}...

[ read more ]

Thursday, May 27, 2010

Cast operators do not obey the distributive law

by Eric Lippert via Fabulous Adventures In Coding on 5/27/2010 1:55:00 PM

Another interesting question from StackOverflow. Consider the following unfortunate situation: object result;bool isDecimal = GetAmount(out result);decimal amount = (decimal)(isDecimal ? result : 0); The developer who wrote this code was quite surprised to discover that it compiles and then throws “invalid cast exception” if the alternative branch is taken. Anyone see why? In regular algebra, multiplication is “distributive” over addition. That is q * (r + s) is the same as q * r + q * s. The ...

[ read more ]

Monday, May 24, 2010

Every Program There Is, Part Nine

by Eric Lippert via Fabulous Adventures In Coding on 5/24/2010 1:24:00 PM

We seem to have a bit of a performance problem here. We could slap a profiler on it, and normally I’d recommend just that. But in this case, let’s solve this problem by thinking. Suppose we’re trying to work out a problem in our previous grammar, say, S[6]. That requires us to work out, among other things, PARENEND[5], BRACKETEND[5], and so on, each of which requires us to work out S[4]. In short, we work out S[4] four times for every time we work out S[6]. Each one of those w ...

[ read more ]

Thursday, April 22, 2010

Every Tree There Is

by Eric Lippert via Fabulous Adventures In Coding on 4/22/2010 2:05:00 PM

Last time we talked about how the number of binary trees with n nodes is C(n), where C(n) is the nth Catalan number. I asked if there were more or fewer trees – not restricted to binary trees – of size n than there are binary trees of size n. If you worked it out, the answer might have surprised you; it is certainly not immediately obvious. First off, a common response I get to this question is immediately "well, since binary trees are a special case of arbitrary trees, there must be more arbit ...

[ read more ]

Monday, April 19, 2010

Every Binary Tree There Is

by Eric Lippert via Fabulous Adventures In Coding on 4/19/2010 1:34:00 PM

The other day I wrote a little algorithm that did some operation on binary trees. I wanted to test it. I whipped up a few little test cases and it seemed fine, but I wasn’t quite satisfied. I was pretty confident, but maybe there was some odd binary tree topology that I hadn’t considered which would cause a bug. I reasoned that there have got to be only a finite number of binary tree topologies of a given size. I’ll just try all of them. Before I go on, I need a compact notation for a binary tr ...

[ read more ]

Every Binary Tree There Is

by Eric Lippert via Fabulous Adventures In Coding on 4/19/2010 1:34:00 PM

The other day I wrote a little algorithm that did some operation on binary trees. I wanted to test it. I whipped up a few little test cases and it seemed fine, but I wasn’t quite satisfied. I was pretty confident, but maybe there was some odd binary tree topology that I hadn’t considered which would cause a bug. I reasoned that there have got to be only a finite number of binary tree topologies of a given size. I’ll just try all of them. Before I go on, I need a compact notation for a binary tr ...

[ read more ]

Monday, April 12, 2010

Ignoring parentheses

by Eric Lippert via Fabulous Adventures In Coding on 4/12/2010 1:53:00 PM

Yet another amusing question from StackOverflow: is there a difference between “return something;” and “return (something);” in C#? In practice, there is no difference. In theory there could be a difference. There are three interesting points in the C# specification where this could present a problem. First, conversion of anonymous functions to delegate types and expression trees. Consider the following: Func<int> F1() { return ()=>1; } Func<int> F2() { return (()=>1); } ...

[ read more ]

Ignoring parentheses

by Eric Lippert via Fabulous Adventures In Coding on 4/12/2010 1:53:00 PM

Yet another amusing question from StackOverflow: is there a difference between “return something;” and “return (something);” in C#? In practice, there is no difference. In theory there could be a difference. There are three interesting points in the C# specification where this could present a problem. First, conversion of anonymous functions to delegate types and expression trees. Consider the following: Func<int> F1() { return ()=>1; } Func<int> F2() { return (()=>1); } ...

[ read more ]

Thursday, April 08, 2010

Precision and accuracy of DateTime

by Eric Lippert via Fabulous Adventures In Coding on 4/8/2010 1:37:00 PM

The DateTime struct represents dates as a 64 bit number that measures the number of “ticks” since a particular start date. Ten million ticks equals one second. That’s a quite high degree of precision. You can represent dates and times to sub-microsecond accuracy with a DateTime, which is typically more precision than you need. Not always, of course; on modern hardware you can probably execute a couple hundred instructions in one tick, and therefore if you want timings that are at the level of p ...

[ read more ]

Precision and accuracy of DateTime

by Eric Lippert via Fabulous Adventures In Coding on 4/8/2010 1:37:00 PM

The DateTime struct represents dates as a 64 bit number that measures the number of “ticks” since a particular start date. Ten million ticks equals one second. That’s a quite high degree of precision. You can represent dates and times to sub-microsecond accuracy with a DateTime, which is typically more precision than you need. Not always, of course; on modern hardware you can probably execute a couple hundred instructions in one tick, and therefore if you want timings that are at the level of p ...

[ read more ]

Thursday, April 01, 2010

Some Last-Minute New C# 4.0 Features

by Eric Lippert via Fabulous Adventures In Coding on 4/1/2010 1:26:00 PM

As I’m sure you know by now, we are done implementing C# 4. We’ve added support for interoperability with dynamic languages and legacy object models, named and optional parameters, the ability to “link” against interfaces from a Primary Interop Assembly, and my favourite feature, covariance and contravariance of interface and delegate types. Now, sometimes we manage to find time in the schedule to fit in small additional features that do not directly align with the larger “theme” of the release ...

[ read more ]

Monday, March 29, 2010

Putting a base in the middle

by Eric Lippert via Fabulous Adventures In Coding on 3/29/2010 1:16:00 PM

UPDATE: I have rewritten this article based on new information I’ve just learned. I should have looked at the design notes archive first! Here’s a crazy-seeming but honest-to-goodness real customer scenario that got reported to me recently. There are three DLLs involved, Alpha.DLL, Bravo.DLL and Charlie.DLL. The classes in each are: public class Alpha // In Alpha.DLL{  public virtual void M()  {    Console.WriteLine("Alpha");  }} public class Bravo: Alpha // In Bra ...

[ read more ]

Thursday, March 18, 2010

Do not name a class the same as its namespace, Part Four

by Eric Lippert via Fabulous Adventures In Coding on 3/18/2010 1:56:00 PM

Part Four: Making the problem worse   I said earlier that the fundamental reason for namespaces in the first place was organization of types into a hierarchy, not separation of two things with similar names. But suppose you are putting something into a namespace because you have two things that are of the same name and need to be kept separate. Suppose you reason “I’m going to put List into its own namespace because List could conflict with another class named List. The user needs to be a ...

[ read more ]

Monday, March 15, 2010

Do not name a class the same as its namespace, Part Three

by Eric Lippert via Fabulous Adventures In Coding on 3/15/2010 1:53:00 PM

Part Three: Bad hierarchical design The reason we humans invented hierarchies in the first place is to organize a complicated body of stuff such that there’s a well-defined place for everything. Any time you see a hierarchy where there are two levels with the same name, something is messed up in the design of that hierarchy. And any time you see a hierarchy where one of the interior nodes has a single child, again, something is probably messed up. Krzysztof points out in the annotated Framework ...

[ read more ]

Thursday, March 11, 2010

Do not name a class the same as its namespace, Part Two

by Eric Lippert via Fabulous Adventures In Coding on 3/11/2010 6:51:00 PM

Part Two: Machine-generated code: You write namespace Foo{  public sealed class Foo  {    public string Blah(int x) { … }  } } You take this code and run a third-party “decorator” tool over it that makes your class into a more colourful class: // Machine-generated code:namespace Foo{  public sealed class ColorFoo  {    public ColorFoo(Foo.Foo foo, System.Drawing.Color color)    {      innerFoo = foo; ...

[ read more ]

Tuesday, March 09, 2010

Do not name a class the same as its namespace, Part One

by Eric Lippert via Fabulous Adventures In Coding on 3/9/2010 2:52:00 PM

The Framework Design Guidelines say in section 3.4 “do not use the same name for a namespace and a type in that namespace”. (*) That is: namespace MyContainers.List{    public class List { … }} Why is this badness? Oh, let me count the ways. Part One: Collisions amongst referenced assemblies: You can get yourself into situations where you think you are referring to one thing but in fact are referring to something else. Suppose you end up in this unfortunate situation: you are wri ...

[ read more ]

Thursday, March 04, 2010

Too much reuse

by Eric Lippert via Fabulous Adventures In Coding on 3/4/2010 2:33:00 PM

A recent user question: I have code that maintains a queue of pending work items waiting to be completed on various different worker threads. In certain unfortunate fatal error situations I complete each of these by throwing an exception. Can I create just one exception object? Are there any issues throwing the same exception object multiple times on multiple threads? Anyone who has ever seen this in a code review knows the answer: catch(Exception ex){   Logger.Log(ex);   ...

[ read more ]

Thursday, February 25, 2010

Careful with that axe, part two: What about exceptions?

by Eric Lippert via Fabulous Adventures In Coding on 2/25/2010 2:59:00 PM

Suppose you’re shutting down the worker thread we were talking about last time, and it throws an exception? What happens? Badness, that’s what. What to do about it? As in our previous discussion, it is better to not be in this situation in the first place: write the worker code so that it does not throw. If you cannot do that, then you have two choices: handle the exception, or don't handle the exception. Suppose you don't handle the exception. As of I think CLR v2, an unhandled exception in a ...

[ read more ]

Monday, February 22, 2010

Careful with that axe, part one: Should I specify a timeout?

by Eric Lippert via Fabulous Adventures In Coding on 2/22/2010 2:41:00 PM

The other day, six years ago, I was was talking a bit about how to decide whether to keep waiting for a bus, or to give up and walk. It led to a quite interesting discussion on the old JoS forum. But what if the choice isn’t “wait for a bit then give up”, instead it is “wait for a bit, and then take an axe to the thread”? A pattern I occasionally see is something like I’ve got a worker thread that I started up, I ask it to shut down, and then I wait for it to do so. If it doesn’t shut down soo ...

[ read more ]

Thursday, February 18, 2010

What’s the difference between ternary and tertiary?

by Eric Lippert via Fabulous Adventures In Coding on 2/18/2010 2:22:00 PM

The conditional operator ( condition ? consequence : alternative ) is often referred to as both the “ternary operator” and the “tertiary operator”. What’s the difference? “Ternary” means “having three parts”. Operators in C# can be unary, binary or ternary – they take one, two or three operands.  “Tertiary” means “third in order”. Compiler flaws noted in bug reports can be of primary, secondary or tertiary importance. Colours can be primary (yellow), secondary (orange) or tertiary (yello ...

[ read more ]

Thursday, February 11, 2010

Chaining simple assignments is not so simple

by Eric Lippert via Fabulous Adventures In Coding on 2/11/2010 2:59:00 PM

UPDATE: I interrupt this episode of FAIC with a request from my friend and colleague Lucian, from the VB team, who wonders whether it is common in C# to take advantage of the fact that assignment expressions are expressions. The most common usage of this pattern is the subject of this blog entry: the fact that "chained" assignment works at all is a consequence of the fact that assignments are expressions, not statements. There are other uses too; one coul ...

[ read more ]

Monday, February 08, 2010

Making the code read like the spec

by Eric Lippert via Fabulous Adventures In Coding on 2/8/2010 2:58:00 PM

As I mentioned a while back, there are some bugs in the compiler code which analyzes whether a set of classes violates the “no cycles” rules for base classes. (That is, a class is not allowed to inherit from itself, directly or indirectly, and not allowed to inherit from one of its own nested classes, directly or indirectly.) The bugs are almost all of the form where we accidentally detect a cycle in suspicious-looking generic code but in fact there is no cycle; the bugs are the result of an at ...

[ read more ]

Monday, February 01, 2010

Style follows semantics

by Eric Lippert via Fabulous Adventures In Coding on 2/1/2010 4:29:00 PM

Which is better style? bool abc;if (Foo())  abc = Bar();else  abc = false; vs bool abc = Foo() && Bar(); ? To me, this comes down to the question “is Bar useful solely for obtaining its value, or also for its side effects?” The stylistic choices should typically be driven by a desire to clearly communicate the semantics of the program fragment. The metasyntatic names are therefore making this harder to answer, not easier. Suppose the choice were in fact between: bool loginSucc ...

[ read more ]

Thursday, January 28, 2010

Calling constructors in arbitrary places

by Eric Lippert via Fabulous Adventures In Coding on 1/28/2010 3:10:00 PM

C# lets you call another constructor from a given constructor, but only before the body of the calling constructor runs: public C(int x) : this(x, null){  // …}public C(int x, string y){  // …} Why can you call another constructor at the beginning of a constructor block, but not at the end of the block, or in the middle of the block? Well, let's break it down into two cases. (1) You're calling a "base" constructor, and (2) you're calling a "this" constructor. For the "base" scenar ...

[ read more ]

Monday, January 25, 2010

Why are unused using directives not a warning?

by Eric Lippert via Fabulous Adventures In Coding on 1/25/2010 3:00:00 PM

As I’ve discussed before, we try to reserve warnings for only those situations where we can say with almost certainty that the code is broken, misleading or useless. One reason for trying to ensure that warnings are not “false positives” is that we don’t ever want to encourage someone to take working, correct code and break it so as to remove the warning. Another is that since many people compile with “warnings are errors” turned on, we do not want to introduce a whole lot of unnecessary build ...

[ read more ]

Thursday, January 21, 2010

What’s the difference between a destructor and a finalizer?

by Eric Lippert via Fabulous Adventures In Coding on 1/21/2010 2:20:00 PM

Today, another dialogue, and another episode of my ongoing series "what's the difference?" What’s the difference, if any, between a “destructor” and a “finalizer”? Both are mechanisms for cleaning up a resource when it is no longer in use. When I was asked this, at first I didn’t think there was a difference. But some Wikipedia searches turned up a difference; the term “destructor” is typically used to mean a deterministically-invoked cleanup, whereas a “finalizer” runs when the garbage collect ...

[ read more ]

Monday, January 18, 2010

A Definite Assignment Anomaly

by Eric Lippert via Fabulous Adventures In Coding on 1/18/2010 2:28:00 PM

UPDATE: I have discovered that this issue is considerably weirder than the initial bug report led me to believe. I've rewritten the examples in this article; the previous ones did not actually demonstrate the bug.  Consider the following code: struct S {  private string blah;  public S(string blah)  {      this.blah = blah;  }  public void Frob()  { // whatever  }} This method body code fragment is legal (though pro ...

[ read more ]

Thursday, January 14, 2010

Why Can't I Access A Protected Member From A Derived Class? Part Six

by Eric Lippert via Fabulous Adventures In Coding on 1/14/2010 2:42:00 PM

Reader Jesse McGrew asks an excellent follow-up question to my 2005 post about why you cannot access a protected member from a derived class. (You probably want to re-read that post in order to make sense of this one.) I want to be clear in my terminology, so I’m going to define some terms. Suppose we have a call foo.Bar() inside class C. The value of foo is the “receiver” of the call. The compile-time type of foo is the “compile time type of the receiver”. The “runtime type of the receiver” co ...

[ read more ]

Monday, January 11, 2010

Continuing to an outer loop

by Eric Lippert via Fabulous Adventures In Coding on 1/11/2010 2:54:00 PM

When you have a nested loop, sometimes you want to “continue” the outer loop, not the inner loop. For example, here we have a sequence of criteria and a sequence of items, and we wish to determine if there is any item which matches every criterion: match = null;foreach(var item in items){  foreach(var criterion in criteria)  {    if (!criterion.IsMetBy(item))    {      // No point in checking anything further; this is not &nb ...

[ read more ]

Thursday, January 07, 2010

Is there such a thing as too much precision?

by Eric Lippert via Fabulous Adventures In Coding on 1/7/2010 3:02:00 PM

Well, enough chit-chat, back to programming language design. Suppose you’re building electronic piano software. As we’ve discussed before, the “equal temperament” tuning for a piano goes like this: the 49th note from the left on a standard 88 key piano is A, and its frequency is 440 Hz. Each octave above or below that doubles or halves the frequency. Why? Because humans perceive the ratio between two frequencies as the relevant factor, not the (subtractive) difference. There are twelve semitone ...

[ read more ]

Saturday, December 26, 2009

It's the most wonderful time of the year

by Eric Lippert via Fabulous Adventures In Coding on 12/26/2009 4:01:00 PM

Here's a little holiday cheer for you all. Or, at least for you all in Commonwealth countries. static object M<T>(T t) where T : struct{  return t;} int ii = 10;int? jj = 20;object xx = ii;object yy = jj;System.ValueType zz = ii;IComparable aa = ii;System.Enum bb = MidpointRounding.ToEven;object cc = M(ii); I hope you're having a festive holiday season. Happy Boxing Day, and we'll see you in the New Year for more fabulous adventures! [Eric is on vacation; this posting is pre-rec ...

[ read more ]

Thursday, December 10, 2009

Constraints are not part of the signature

by Eric Lippert via Fabulous Adventures In Coding on 12/10/2009 5:31:00 PM

What happens here? class Animal { } class Mammal : Animal { } class Giraffe : Mammal { }class Reptile : Animal { } …static void Foo<T>(T t) where T : Reptile { }static void Foo(Animal animal) { }static void Main() {     Foo(new Giraffe()); } Most people assume that overload resolution will choose the second overload. In fact, this program produces a compile error saying that T cannot be Giraffe. Is this a compiler bug? No, this behaviour is correct according to the spec. F ...

[ read more ]

Monday, December 07, 2009

Query transformations are syntactic

by Eric Lippert via Fabulous Adventures In Coding on 12/7/2009 2:20:00 PM

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: from customer in customerListwhere customer.City == "London" select customer.Name Or you can, equivalently, use the “fluent method call” syntax: customerList.Where(customer=>customer.City == "London").Select(customer=>customer.Name) These are guaranteed to be equivalent because the compiler simply transforms the former syntax into the latter syntax ...

[ read more ]

Thursday, December 03, 2009

Exact rules for variance validity

by Eric Lippert via Fabulous Adventures In Coding on 12/3/2009 2:32:00 PM

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 th ...

[ read more ]

Monday, November 30, 2009

What's the difference between covariance and assignment compatibility?

by Eric Lippert via Fabulous Adventures In Coding on 11/30/2009 2:51:00 PM

I've written a lot about this already, but I think one particular point bears repeating. 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. A number of those d ...

[ read more ]

Monday, November 23, 2009

Always write a spec, Part Two

by Eric Lippert via Fabulous Adventures In Coding on 11/23/2009 3:01:00 PM

Upon submitting that specification for review, even before seeing my code, Chris found a bug and an omission. 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. The bug is that this line is wrong: if x is ref/out instance.field then add var temp=instanc ...

[ read more ]

Monday, November 16, 2009

Closing over the loop variable, part two

by Eric Lippert via Fabulous Adventures In Coding on 11/16/2009 4:18:00 PM

Thanks to everyone who left thoughtful and insightful comments on last week's post. More countries 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. But what I can deduce from reading the comments is that there is a general lack of consensus on what the ri ...

[ read more ]

Thursday, November 12, 2009

Closing over the loop variable considered harmful

by Eric Lippert via Fabulous Adventures In Coding on 11/12/2009 2:50:00 PM

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 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. But I'm getting ahead of myself. What's the output of this fragment? var values = new List<int>() { 100, 110, ...

[ read more ]

Monday, November 09, 2009

Three Umpires

by Eric Lippert via Fabulous Adventures In Coding on 11/9/2009 3:01:00 PM

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." The second umpire says "Hmph. I calls 'em as they are." The third umpire slowly looks at his two colleagues and declares "They ain't nothin' until I calls 'em." 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. Such a ...

[ read more ]

Thursday, November 05, 2009

Simple names are not so simple, Part Two, plus, volcanoes and fried foods

by Eric Lippert via Fabulous Adventures In Coding on 11/5/2009 2:52:00 PM

I've returned from a brief 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 Ocean, entirely made out of volcanoes. Weird! But delightful. The most impressive thing about the Hawaiian Islands for me was just how obvious were -- even to my completely untrained eyes -- the geomechanical and fluvial processes which shaped the landscape. The mountains and crater ...

[ read more ]

Monday, November 02, 2009

Simple names are not so simple

by Eric Lippert via Fabulous Adventures In Coding on 11/2/2009 2:23:00 PM

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. To begin with, it will be vital to understand the difference between scope and declaration space. To refresh your memory of my earlier article: the scope of an entity is th ...

[ read more ]

Thursday, October 29, 2009

I have a Fit, but a lack of Focus.

by Eric Lippert via Fabulous Adventures In Coding on 10/29/2009 1:54:00 PM

Here's a statement I read the other day about making comparisons between objects of reference type in C#: Object.ReferenceEquals(x,y) returns true if and only if x and y refer to the same object. True or false? 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 ...

[ read more ]

Thursday, October 15, 2009

As Timeless As Infinity

by Eric Lippert via Fabulous Adventures In Coding on 10/15/2009 1:25:00 PM

User: 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, but rather returns an "infinity". Why is that? Eric: As I've often said, "why" questions are difficult for me 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. ...

[ read more ]

Monday, October 12, 2009

Absence of evidence is not evidence of absence

by Eric Lippert via Fabulous Adventures In Coding on 10/12/2009 1:51:00 PM

Today, two more subtly incorrect myths about C#. As you probably know, C# requires all local variables to be explicitly assigned before they are read, but assumes that all class instance field variables are initially assigned to default values. An explanation of why that is that I sometimes hear is "the compiler can easily prove that a local variable is not assigned, but it is much harder to prove that an instance field is not assigned. And since the class's default constructor automatical ...

[ read more ]

Thursday, October 08, 2009

What's the difference between "as" and "cast" operators?

by Eric Lippert via Fabulous Adventures In Coding on 10/8/2009 4:36:00 PM

Most people will tell you that the difference between "(Alpha) bravo" and "bravo as Alpha" is that the former throws an exception if the conversion fails, whereas the latter returns null. Though this is correct, and this is the most obvious difference, it's not the only difference. There are pitfalls to watch out for here. First off, since the result of the "as" operator can be null, the resulting type has to be one that takes a null value: either a reference type or a nullable value type. You ...

[ read more ]

Monday, October 05, 2009

Why No Extension Properties?

by Eric Lippert via Fabulous Adventures In Coding on 10/5/2009 4:29:00 PM

I'm frequently asked "you guys added extension methods to C# 3, so why not add extension properties as well?"  Good question. First, let me talk a bit about C# 3. Clearly the big feature in C# 3 was LINQ. In a sense we had only three features in C# 3: everything necessary for LINQ -- implicitly typed locals, anonymous types, lambda expressions, extension methods, object and collection initializers, query comprehensions, expression trees, improved method type inference partial methods auto ...

[ read more ]

Thursday, October 01, 2009

Why does char convert implicitly to ushort but not vice versa?

by Eric Lippert via Fabulous Adventures In Coding on 10/1/2009 7:53:00 PM

Another good question from StackOverflow. Why is there an implicit conversion from char to ushort, but only an explicit conversion from ushort to char? Why did the designers of the language believe that these asymmetrical rules were sensible rules to add to the language? Well, first off, the obvious things which would prevent either conversion from being implicit do not apply. A char is implemented as an unsigned 16 bit integer that represents a character in a UTF-16 encoding, so it can be conv ...

[ read more ]

Monday, September 28, 2009

String interning and String.Empty

by Eric Lippert via Fabulous Adventures In Coding on 9/28/2009 4:23:00 PM

Here's a curious program fragment: object obj = "Int32";string str1 = "Int32";string str2 = typeof(int).Name;Console.WriteLine(obj == str1); // trueConsole.WriteLine(str1 == str2); // trueConsole.WriteLine(obj == str2); // false !? Surely if A equals B, and B equals C, then A equals C; that's the transitive property of equality. It appears to have been thoroughly violated here. Well, first off, though the transitive property is desirable, this is just one of many situations in which equality is ...

[ read more ]

Thursday, September 24, 2009

Why is covariance of value-typed arrays inconsistent?

by Eric Lippert via Fabulous Adventures In Coding on 9/24/2009 4:53:00 PM

Another interesting question from StackOverflow: uint[] foo = new uint[10];object bar = foo;Console.WriteLine("{0} {1} {2} {3}",          foo is uint[], // True  foo is int[],  // False  bar is uint[], // True  bar is int[]); // TrueWhat the heck is going on here? This program fragment illustrates an interesting and unfortunate inconsistency between the CLI type system and the C# type system. The CLI has the co ...

[ read more ]

Monday, September 21, 2009

Why do ref and out parameters not allow type variation?

by via Fabulous Adventures In Coding on 9/21/2009 4:36:00 PM

Here's a good question from StackOverflow: If you have a method that takes an "X" then you have to pass an expression of type X or something convertible to X. Say, an expression of a type derived from X. But if you have a method that takes a "ref X", you have to pass a ref to a variable of type X, period. Why is that? Why not allow the type to vary, as we do with non-ref calls? Let's suppose you have classes Animal, Mammal, Reptile, Giraffe, Turtle and Tiger, with the obvious subclassing relati ...

[ read more ]

Monday, September 14, 2009

What's the difference between a partial method and a partial class?

by Eric Lippert via Fabulous Adventures In Coding on 9/14/2009 6:16:00 PM

Like "fixed" and "into", "partial" is also used in two confusingly similar-yet-different ways in C#. The purpose of a partial class is to allow you to textually break up a class declaration into multiple parts, usually parts found in separate files. The motivation for this feature was machine-generated code that is to be extended by the user by adding to it directly. When you draw a form in the forms designer, the designer generates a class for you representing that form. You can then further ...

[ read more ]

Thursday, September 10, 2009

What's the difference between conditional compilation and the conditional attribute?

by via Fabulous Adventures In Coding on 9/10/2009 5:12:00 PM

User: Why does this program not compile correctly in the release build? class Program { #if DEBUG     static int testCounter = 0; #endif     static void Main(string[] args)     {         SomeTestMethod(testCounter++);     }     [Conditional("DEBUG")]     static void SomeTestMethod(int t) { } } Eric: This fails to compile in the retail build because testCounter ...

[ read more ]

Monday, August 31, 2009

What's the Difference, Part Four: into vs into

by Eric Lippert via Fabulous Adventures In Coding on 8/31/2009 4:30:00 PM

The keyword "into" in a query comprehension means two different things, depending on whether it follows a join or select/group. If it follows a join, it turns a join into a group join. If it follows a select or group then it introduces a query continuation. These two features are quite different, but easily confused. First, the group join. Suppose you've got a key -- a customer id number -- that is used as the primary key of a collection of customers, and as a foreign key of a collection of cre ...

[ read more ]

Thursday, August 27, 2009

What's the Difference? Part Three: fixed vs. fixed

by Eric Lippert via Fabulous Adventures In Coding on 8/27/2009 4:43:00 PM

I got an email the other day that began: I have a question about fixed sized buffers in C#:  unsafe struct FixedBuffer { public fixed int buffer[100]; } Now by declaring buffer as fixed it is not movable... And my heart sank. This is one of those deeply unfortunate times when subtle choices made in the details of language design encourage misunderstandings. When doing pointer arithmetic in unsafe code on a managed object, you need to make sure that the garbage collector does not move ...

[ read more ]

Monday, August 24, 2009

Iterator Blocks Part Seven: Why no anonymous iterators?

by Eric Lippert via Fabulous Adventures In Coding on 8/24/2009 4:23:00 PM

This annotation to a comment in part five I think deserves to be promoted to a post of its own. Why do we disallow anonymous iterators? I would love to have anonymous iterator blocks.  I want to say something like: IEnumerable<int> twoints = ()=>{ yield return x; yield return x*10; }; foreach(int i in twoints) ... It would be totally awesome to be able to build yourself a little sequence generator in-place that closed over local variables. The reason why not is straightforward: ...

[ read more ]

Monday, August 17, 2009

Arrays of arrays

by Eric Lippert via Fabulous Adventures In Coding on 8/17/2009 2:25:00 PM

Most people understand that there’s a difference between a “rectangular” and a “ragged” two-dimensional array. int[,] rectangle = {   {10, 20},   {30, 40},   {50, 60} };int[][] ragged = {   new[] {10},   new[] {20, 30},   new[] {40, 50, 60} }; Here we have a two-dimensional array with six elements, arranged in three rows of two elements each. And we have a one-dimensional array with three elements, where each element is itself a one-dimensional array with one, two ...

[ read more ]

Thursday, August 13, 2009

Four switch oddities

by Eric Lippert via Fabulous Adventures In Coding on 8/13/2009 1:33:00 PM

The C# switch statement is a bit weird. Today, four quick takes on things you probably didn't know about the switch statement. Case 1: You probably know that it is illegal to "fall through" from one switch section to another: switch(attitude){  case Attitude.HighAndMighty:    Console.WriteLine("High");    // we want to fall through, but this is an error  case Attitude.JustMighty:    Console.WriteLine("Mighty");    break;} Bu ...

[ read more ]

Thursday, August 06, 2009

Not everything derives from object

by Eric Lippert via Fabulous Adventures In Coding on 8/6/2009 1:45:00 PM

I hear a lot of myths about C#. Usually the myths have some germ of truth to them, like "value types are always allocated on the stack". If you replace "always" with "sometimes", then the incorrect mythical statement becomes correct. One I hear quite frequently is "in C# every type derives from object". Not true! First off, no pointer types derive from object, nor are any of them convertible to object. Unsafe pointer types are explicitly outside of the normal type rules for the language. (If y ...

[ read more ]

Monday, August 03, 2009

What's The Difference, Part Two: Scope vs Declaration Space vs Lifetime

by Eric Lippert via Fabulous Adventures In Coding on 8/3/2009 2:08:00 PM

"Scope" has got to be one of the most confusing words in all of programming language design. People seem to use it casually to mean whatever is convenient at the time; I most often see it confused with lifetime and declaration space. As in "the memory will be released when the variable goes out of scope". In an informal setting, of course it is perfectly acceptable to use "scope" to mean whatever you want, so long as the meaning is clearly communicated to the audience. In a more formal setting, ...

[ read more ]

Thursday, July 30, 2009

What's the difference, part one: Generics are not templates

by Eric Lippert via Fabulous Adventures In Coding on 7/30/2009 1:58:00 PM

Because I'm a geek, I enjoy learning about the sometimes-subtle differences between easily-confused things. For example: I'm still not super-clear in my head on the differences between a hub, router and switch and how it relates to the gnomes that live inside of each. Hunks of minerals found in nature are rocks; as soon as you put them in a garden or build a bridge out of them, suddenly they become stones. When a pig hits 120 pounds, it's a hog. I thought I might do an occasional series o ...

[ read more ]

Monday, July 27, 2009

Iterator Blocks, Part Six: Why no unsafe code?

by Eric Lippert via Fabulous Adventures In Coding on 7/27/2009 2:07:00 PM

There are three good reasons to disallow unsafe blocks inside an iterator block. First, it is an incredibly unlikely scenario. The purpose of iterator blocks is to make it easy to write an iterator that walks over some abstract data type. This is highly likely to be fully managed code; it's simply not a by-design scenario. Second, the scenario is a violent mixing of "levels." You think of the level of abstraction of a programming language feature as how "far from the machine" the fea ...

[ read more ]

Thursday, July 23, 2009

Iterator Blocks, Part Five: Push vs Pull

by Eric Lippert via Fabulous Adventures In Coding on 7/23/2009 2:05:00 PM

A while back I posted some commentary I did for the Scripting Summer Games where I noted that there is an isomorphism between "pull" sequences and "push" events. Normally you think of events as something that "calls you", pushing the event arguments at you. And normally you think of a sequence as something that you "pull from", asking it for the next value until you're done. But you can treat a stream of event firings as being a sequence of event argument objects. And similarly, you could imple ...

[ read more ]

Monday, July 20, 2009

Iterator blocks Part Four: Why no yield in catch?

by Eric Lippert via Fabulous Adventures In Coding on 7/20/2009 1:44:00 PM

Now that you know why we disallow yielding in a finally, it’s pretty straightforward to see why we also disallow yielding in a catch. First off, we still have the problem that it is illegal to “goto” into the middle of the handler of a try-protected region. The only way to enter a catch block is via the “non-local goto” that is catching an exception. So once you yielded out of the catch block, the next time MoveNext was called, we’d have no way to get back into the catch block where we left of ...

[ read more ]

Thursday, July 16, 2009

Iterator Blocks, Part Three: Why no yield in finally?

by Eric Lippert via Fabulous Adventures In Coding on 7/16/2009 1:18:00 PM

There are three scenarios in which code could be executing in a finally in an iterator block. In none of them is it a good idea to yield a value from inside the finally, so this is illegal across the board. The three scenarios are (1) normal cleanup, (2) exception cleanup, and (3) iterator disposal. For the first scenario, suppose we have something like try{  Setup();  yield return M();}finally{  yield return N();  Cleanup();} How should we transform this into an iterator st ...

[ read more ]

Monday, July 13, 2009

Iterator Blocks, Part Two: Why no ref or out parameters?

by Eric Lippert via Fabulous Adventures In Coding on 7/13/2009 1:35:00 PM

A long and detailed discussion of how exactly we implement iterator blocks would take me quite a while, and would duplicate work that has been done well by others already. I encourage you to start with Raymond’s series, which is a pretty gentle introduction: part 1, part 2, part 3. If you want a more detailed look at how this particular sausage is made, Jon’s article is quite in-depth. To make a long story short, we implement iterators by: Spitting a class that implements the relevant interfac ...

[ read more ]

Monday, July 06, 2009

Color Color

by Eric Lippert via Fabulous Adventures In Coding on 7/6/2009 1:29:00 PM

Pop quiz: What does the following code do when compiled and run? class C{    public static void M(string x)    {        System.Console.WriteLine("static M(string)");    }    public void M(object s)    {        System.Console.WriteLine("M(object)");    } }class Program{    static void Main()    {  & ...

[ read more ]

Monday, June 29, 2009

The void is invariant

by Eric Lippert via Fabulous Adventures In Coding on 6/29/2009 2:30:00 PM

[UPDATES below]  A while back I described a kind of variance that we’ve supported since C# 2.0. When assigning a method group to a delegate type, such that both the selected method and the delegate target agree that their return type is a reference type, then the conversion is allowed to be covariant. That is, you can say: Giraffe GetGiraffe() { … }…Func<Animal> f = GetGiraffe; This works logically because anyone who calls f must be able to handle any animal that comes back. The actu ...

[ read more ]

Thursday, June 25, 2009

Mmm, Curry

by Eric Lippert via Fabulous Adventures In Coding on 6/25/2009 1:51:00 PM

A recent comment asked why Haskell programmers sometimes write C# lambdas in this style: Func<int, Func<int, int>> add = x=>y=>x+y; which is then invoked as sum = add(2)(3); because of course the first invocation returns a function that adds two, which is then invoked with three. Why do that instead of the more straightforward Func<int, int, int> add = (x,y)=>x+y; and invoke it as sum = add(2,3); ??? I was going to write a short article on that when I remembered tha ...

[ read more ]

Wednesday, June 24, 2009

It Already Is A Scripting Language

by Eric Lippert via Fabulous Adventures In Coding on 6/24/2009 3:07:00 PM

My recent post about the possibility of considering maybe someday perhaps adding "top level" methods to C# in order to better enable "scripty" scenarios generated a surprising amount of immediate emphatic pushback. Check out the comments to see what I mean. Two things immediately come to mind. First off, the suggestion made by a significant number of the commenters is "instead of allowing top-level methods, strengthen the using directive." That is, if you said "using System.Math;" then all the ...

[ read more ]

Monday, June 22, 2009

Why Doesn't C# Implement "Top Level" Methods?

by Eric Lippert via Fabulous Adventures In Coding on 6/22/2009 3:39:00 PM

C# requires that every method be in some class, even if it is a static method in a static class in the global namespace. Other languages allow "top level" functions. A recent stackoverflow post asks why that is. I am asked "why doesn't C# implement feature X?" all the time. The answer is always the same: because no one ever designed, specified, implemented, tested, documented and shipped that feature. All six of those things are necessary to make a feature happen. All of them cost huge amounts ...

[ read more ]

Thursday, June 18, 2009

Use your legs, not your back

by Eric Lippert via Fabulous Adventures In Coding on 6/18/2009 1:32:00 PM

In C# you can "lift", "raise" and "hoist", and they all mean different things. To "lift" an operator is to take an operator that operates on non-nullable value types, and create from it a similar operator that operates on nullable value types. (We are a little bit inconsistent in exactly how we use the word "lifted", which I documented here.) For example, if you have  public static Complex operator +(Complex x, Complex y) { ... }  then we automatically generate a lifted operator for ...

[ read more ]

Thursday, June 11, 2009

What does the optimize switch do?

by Eric Lippert via Fabulous Adventures In Coding on 6/11/2009 1:57:00 PM

I was asked recently exactly what optimizations the C# compiler performs when you specify the optimize switch. Before I answer that, I want to make sure that something is perfectly clear. The compiler’s “usage” string is not lying when it says: /debug[+|-]     Emit debugging information/optimize[+|-]  Enable optimizations Emitting debug information and optimizing the generated IL are orthogonal; they have no effect on each other at all (*). The usual thing to do is to ...

[ read more ]

Monday, June 01, 2009

Bug Psychology

by Eric Lippert via Fabulous Adventures In Coding on 6/1/2009 1:48:00 PM

Fixing bugs is hard. For the purposes of this posting, I’m talking about those really “crisp” bugs -- those flaws which are entirely due to a failure on the developer’s part to correctly implement some mechanistic calculation or ensure some postcondition is met. I’m not talking about oops, we just found out that the product name sounds like a rude word in Urdu, or the specification wasn’t quite right so we changed it or the code wasn’t adequately robust in the face of a buggy caller. I mean tho ...

[ read more ]

Monday, May 25, 2009

Why Is The Return Type Parameter Last?

by Eric Lippert via Fabulous Adventures In Coding on 5/25/2009 5:09:00 PM

The generic delegate type Func<A, R> is defined as delegate R Func<A, R>(A arg). That is, the argument type is to the left of return type in the declaration of the generic type parameters, but to the right of the return type when they are used. What’s up with that? Wouldn’t it be a lot more natural to define it as delegate R Func<R, A>(A arg), so that the R’s and A’s go together? Maybe in C# it would, but in this case, it’s C# that’s the crazy one. When we speak it in English ...

[ read more ]

Thursday, May 21, 2009

In Foof We Trust: A Dialogue

by Eric Lippert via Fabulous Adventures In Coding on 5/21/2009 2:54:00 PM

User: The typeof(T) operator in C# essentially means “compiler, generate some code that gives me an object at runtime which represents the type you associate with the name T”. It would be nice to have similar operators that could take names of, say, methods and give you other metadata objects, like method infos, property infos, and so on. This would be a more pleasant syntax than passing ugly strings and types and binding flags to various Reflection APIs to get that information. Eric: I agree, ...

[ read more ]

Monday, May 18, 2009

“foreach” vs “ForEach”

by Eric Lippert via Fabulous Adventures In Coding on 5/18/2009 2:13:00 PM

A number of people have asked me why there is no Microsoft-provided “ForEach” sequence operator extension method. The List class has such a method already of course, but there’s no reason why such a method could not be created as an extension method for all sequences. It’s practically a one-liner: public static void ForEach<T>(this IEnumerable<T> sequence, Action<T> action){ // argument null checking omitted  foreach(T item in sequence) action(item);} My usual response to ...

[ read more ]

Thursday, May 14, 2009

Null Is Not Empty

by Eric Lippert via Fabulous Adventures In Coding on 5/14/2009 2:47:00 PM

Back when I started this blog in 2003, one of the first topics I posted on was the difference between Null, Empty and Nothing in VBScript. An excerpt: Suppose you have a database of sales reports, and you ask the database "what was the total of all sales in August?" but one of the sales staff has not reported their sales for August yet. What's the correct answer? You could design the database to ignore the fact that data is missing and give the sum of the known sales, but that would be answeri ...

[ read more ]

Monday, May 11, 2009

Reserved and Contextual Keywords

by Eric Lippert via Fabulous Adventures In Coding on 5/11/2009 3:07:00 PM

Many programming languages, C# included, treat certain sequences of letters as “special”. Some sequences are so special that they cannot be used as identifiers. Let’s call those the “reserved keywords” and the remaining special sequences we’ll call the “contextual keywords”. They are “contextual” because the character sequence might one meaning in a context where the keyword is expected and another in a context where an identifier is expected.* The C# specification defines the following reserv ...

[ read more ]

Thursday, May 07, 2009

Zip Me Up

by Eric Lippert via Fabulous Adventures In Coding on 5/7/2009 2:19:00 PM

Suppose you’ve got a sequence of Foos and you want to project from that a sequences of Bars. That’s straightforward using LINQ: IEnumerable<Bars> bars = from foo in foos select MakeBar(foo); or, without the query sugar: IEnumerable<Bars> bars = foos.Select(foo=>MakeBar(foo)); But what if you have two sequences that you want to project from? Say you’ve got two sequences of doubles that are the same length, and you want to project a sequences of points. The operation of “project fr ...

[ read more ]

Thursday, April 09, 2009

Double Your Dispatch, Double Your Fun

by Eric Lippert via Fabulous Adventures In Coding on 4/9/2009 3:50:00 PM

Here’s an interesting question I got the other day: If you have an overloaded operator == then any call to the operator method is “early bound” at compile time according to the compile-time types of the operands. But calling Equals() on an object is a virtual call; the actual method called is bound at runtime according to the runtime type of the receiver. This difference seems weird to me. What’s the relevant design principle here? The short answer is that language designers and framewo ...

[ read more ]

Monday, March 30, 2009

Every Problem Looks Like A Nail

by Eric Lippert via Fabulous Adventures In Coding on 3/30/2009 3:10:00 PM

I wish all the questions I got were this straightforward: “I need to compare two strings for non-culture-sensitive equality. I notice that there are methods String.Equals and String.Compare which can both do that. What is the guideline on which one I should use?” I’ll answer your question, but first, a funny story (*). My buddy Steve and I were fixing the flashing that is leaking around the seal between my roof and my chimney the other day. “Steve,” I said, “hand me that screwdriver.” Steve h ...

[ read more ]

Thursday, March 19, 2009

Representation and Identity

by Eric Lippert via Fabulous Adventures In Coding on 3/19/2009 1:46:00 PM

I get a fair number of questions about the C# cast operator. The most frequent question I get is: short sss = 123;object ooo = sss;            // Box the short.int iii = (int) sss;         // Perfectly legal.int jjj = (int) (short) ooo; // Perfectly legalint kkk = (int) ooo;         // Invalid cast exception?! Why? Why? Because a boxed T can only be unboxed to T ...

[ read more ]

Tuesday, March 10, 2009

Loops are gotos

by Eric Lippert via Fabulous Adventures In Coding on 3/10/2009 4:42:00 PM

Here's an interesting question I got the other day: We are writing code to translate old mainframe business report generation code written in a BASIC-like language to C#. The original language allows "goto" branching from outside of a loop to the interior of a loop, but C# only allows branching the other way, from the interior to the exterior. How can we branch to the inside of a loop in C#? I can think of a number of ways to do that. First, don't do it. Write your translator so that it detect ...

[ read more ]

Friday, March 06, 2009

Locks and exceptions do not mix

by Eric Lippert via Fabulous Adventures In Coding on 3/6/2009 4:41:00 PM

A couple years ago I wrote a bit about how our codegen for the lock statement could sometimes lead to situations in which an unoptimized build had different potential deadlocks than an optimized build of the same source code. This is unfortunate, so we've fixed that for C# 4.0. However, all is still not rainbows, unicorns and Obama, as we'll see. Recall that lock(obj){body} was a syntactic sugar for var temp = obj;Monitor.Enter(temp);try { body }finally { Monitor.Exit(temp); } The problem here ...

[ read more ]

Friday, February 06, 2009

Santalic tailfans, part two

by Eric Lippert via Fabulous Adventures In Coding on 2/6/2009 6:19:31 PM

As I have said before many times, there is only one sensible way to make a performant application. (As an aside: perfectly good word, performant, deal with it!) That is: Set meaningful, measurable, customer-focused goals. Write the code to be as clear and correct as possible. Carefully measure your performance against your goals. Did you meet your goal? Great! Don't waste any time on performance analysis. Spend your valuable time on features, documentation, bug fixing, robustness, security, ...

[ read more ]

Wednesday, February 04, 2009

A nasality talisman for the sultana analyst

by Eric Lippert via Fabulous Adventures In Coding on 2/4/2009 9:52:48 PM

The other day my charming wife Leah and I were playing Scrabble Brand Crossword Game (a registered trademark of Hasbro and Mattel) as is our wont. I went first, drawing the Q and a bunch of vowels. Knowing that the Q is death to hold onto, I immediately opened with QI for 22 points. I silently thanked Miriam-Webster for adding QI, KI and ZA to the OSPD 4th edition. My thankfulness was short-lived, as Leah thought for a few moments and then played ANALYST, for the fifty point "bingo" bonus, ma ...

[ read more ]

Monday, February 02, 2009

Properties vs. Attributes

by Eric Lippert via Fabulous Adventures In Coding on 2/2/2009 9:02:26 PM

Here is yet another question I got from a C# user recently: I have a class that represents a business rule. I want to add some rule metadata that could be used by consumers to retrieve a friendlier rule name, description, and anything else that makes sense. Should this information be exposed as an attribute or property on the class? I would say to absolutely go for a property in this case, for four reasons. First, properties are highly discoverable. Consumers of this class can use IntelliSens ...

[ read more ]

Wednesday, January 28, 2009

Long division

by Eric Lippert via Fabulous Adventures In Coding on 1/28/2009 6:10:56 PM

A thing that makes a reader go hmmm is why in C#, int divided by long has a result of long, even though it is clear that when an int is divided by a (nonzero) long, the result always fits into an int. I agree that this is a bit of a head scratcher. After scratching my head for a while, two reasons to not have the proposed behaviour came to mind. First, why is it even desirable to have the result fit into an int? You'd be saving merely four bytes of memory and probably cheap stack memory at that ...

[ read more ]

Monday, January 26, 2009

Why no var on fields?

by Eric Lippert via Fabulous Adventures In Coding on 1/26/2009 5:59:00 PM

In my recent request for things that make you go hmmm, a reader notes that you cannot use "var" on fields. Boy, would I ever like that. I write this code all the time: private static readonly Dictionary<TokenKind, string> niceNames =   new Dictionary<TokenKind, string>()   {    {TokenKind.Integer, "int"}, ... Yuck. It would be much nicer to be able to write private static readonly var niceNames =   new Dictionary<TokenKind, string>()... You'd thin ...

[ read more ]

Wednesday, January 14, 2009

Automatic vs Explicit Properties

by Eric Lippert via Fabulous Adventures In Coding on 1/14/2009 5:11:25 PM

Here's a question I got from a C# user last year, a question I get fairly frequently: User: With “regular” explicit properties, I tend to use the private backing field directly from within the class. Of course, with an automatic property, you can’t do this. My concern is that in the future, if I decide I need an explicit property for whatever reason, I’m left with the choice of changing the class implementation to use the new private field, or continue going through the property. I’m not sure ...

[ read more ]

Friday, November 07, 2008

The Future Of C#, Part Five

by Eric Lippert via Fabulous Adventures In Coding on 11/7/2008 4:18:00 PM

When we're designing a new version of the language, something we think about a lot is whether the proposed new features "hang together". Having a consistent "theme" to a release makes it easier for us to prioritize and organize proposals, it makes it easier for our marketing and user education people to effectively communicate with customers, it's just all-around goodness. If you look at C# 2.0, it was a bit of a grab-bag. The big features were clustered around the notion of enabling rich, type ...

[ read more ]