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

Monday, February 13, 2012

Bad Metaphors

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

The standard way to teach beginner OO programmers about classes is to make a metaphor to the real world. And indeed, I do this all the time in this blog, usually to the animal kingdom. A "class" in real life codifies a commonality amongst a certain set of objects: mammals, for example, have many things in common; they have backbones, can grow hair, can make their own heat, and so on. A class in a programming language does the same thing: codifies a commonality amongst a certain set of objects v ...

[ read more ]

Monday, February 06, 2012

What is "binding" and what makes it late?

by Eric Lippert via Fabulous Adventures In Coding on 2/6/2012 6:39:00 PM

"Late binding" is one of those computer-sciency terms that, like "strong typing", means different things to different people. I thought I might describe what the term means to me. First off, what is "binding"? We can't understand what it means to bind late if we don't know what it is to bind at all. A compiler is by definition a device which takes in a text written in one language and outputs code that "means the same thing" in another language. The compiler I work on, for example, takes in C# ...

[ read more ]

Monday, January 23, 2012

Anonymous types unify within an assembly, Part One

by Eric Lippert via Fabulous Adventures In Coding on 1/23/2012 3:55:00 PM

Back in my last post of 2010 I said that I would do an example of anonymous types unifying within an assembly "in the new year". I meant 2011, but here we are "in the new year" again, so, no time like the present. The C# specification guarantees you that when you use "the same" anonymous type in two places in one assembly (*) the types unify into one type. In order to be "the same", the two anonymous types have to have the exact same member names and the exact same member types, in the exact sa ...

[ read more ]

Monday, January 09, 2012

Every public change is a breaking change

by Eric Lippert via Fabulous Adventures In Coding on 1/9/2012 5:08:00 PM

Here's an inconvenient truth: just about every "public surface area" change you make to your code is a potential breaking change. First off, I should clarify what I mean by a "breaking change" for the purposes of this article. If you provide a component to a third party, then a "breaking change" is a change such that the third party's code compiled correctly with the previous version, but the change causes a recompilation to fail. (A more strict definition would be that a breaking change is on ...

[ read more ]

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 ]

Wednesday, October 29, 2008

The Future of C#, Part Three: On video, plus the dead-trees edition

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

Amazingly enough, it has happened again. Why does this keep happening to me? Anders, Mads and Eric on C# 4.0: C# 4.0 with Anders Hejlsberg, Mads Torgersen, and Eric Lippert - Part 1 of 2 C# 4.0 with Anders Hejlsberg, Mads Torgersen, and Eric Lippert - Part 2 of 2 Anders, Mads and Scott on the new dead-trees edition of the C# 3.0 specification: The C# Programming Language, 3rd Edition Enjoy! ...

[ read more ]

Tuesday, October 28, 2008

The Future of C#, Part Two

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

Well, I intended to spend the last three weeks blogging about C# design process in anticipation of our announcements at the PDC, and then I got crazy busy at work and never managed to do so! As I'm sure you know by now, we have announced the existence and feature set of that hitherto hypothetical language C# 4.0. Of course I'll be blogging extensively about that over the next year; today though I want to pick up where I left off last time and talk about the tragedy of Object Happiness Disease. ...

[ read more ]

Wednesday, October 08, 2008

The Future of C#, Part One

by Eric Lippert via Fabulous Adventures In Coding on 10/8/2008 3:06:00 PM

An attentive reader pointed me at this long thread on a third-party forum where some people are musing about possible future features of C#. There is far, far more here than I possibly have time to respond to in any kind of detail. Also, I am not going to spill the beans. Anders is giving a talk at the PDC at the end of the month. His talk is titled "The Future of C#" and I'm not going to steal Anders' thunder (or give our marketing department conniptions) by giving specific details a ...

[ read more ]

Friday, September 26, 2008

Preventing third-party derivation, part one

by Eric Lippert via Fabulous Adventures In Coding on 9/26/2008 3:17:00 PM

In this episode of FAIC, a conversation I had with a C# user recently. Next time, some further thoughts on how to use the CLR security system in this sort of scenario. Him: I have this abstract class defined in one assembly: // Assembly FooBar.DLLpublic abstract class Foo{    internal abstract void DoSomething();// ...} I want to create a concrete class derived directly from Foo in another assembly, Blah.DLL. Me: You are going to have to learn to live with disappointment. Hi ...

[ read more ]

Monday, September 22, 2008

Arrays considered somewhat harmful

by Eric Lippert via Fabulous Adventures In Coding on 9/22/2008 6:04:00 PM

I got a moral question from an author of programming language textbooks the other day requesting my opinions on whether or not beginner programmers should be taught how to use arrays. Rather than actually answer that question, I gave him a long list of my opinions about arrays, how I use arrays, how we expect arrays to be used in the future, and so on. This gets a bit long, but like Pascal, I didn't have time to make it shorter.  Let me start by saying when you definitely sh ...

[ read more ]

Tuesday, June 17, 2008

Method Type Inference Changes, Part One

by Eric Lippert via Fabulous Adventures In Coding on 6/17/2008 3:20:00 PM

I want to start this by discussing the purpose of method type inference, and clearing up some potential misunderstandings about type inference errors. First off though, a brief note on nomenclature. Throughout this series when I say "type inference" I mean "method type inference", not any of the other forms of type inference we have in C# 3.0. (Implicitly typed locals, implicitly typed arrays, and so on.) The purpose of type inference is to allow generic methods to be called without explicitly ...

[ read more ]

Wednesday, May 28, 2008

Method Type Inference Changes, Part Zero

by Eric Lippert via Fabulous Adventures In Coding on 5/28/2008 3:16:00 PM

Back in November I wrote a bit about a corner case in method type inference which does not work as expected or as specified in C# 3.0. A number of people made blog comments, sent me mail, and entered "Connect" issues with additional problems and ideas for how we could improve this algorithm. (Particular thanks to nikov for his many fascinating and detailed Connect reports.) As a result, as soon as I had time I embarked upon a detailed review of the method type inference specification and the im ...

[ read more ]

Friday, May 23, 2008

Precedence vs Associativity vs Order

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

Raymond has written about this, I have written about Raymond writing about it, but I still frequently get questions from people who are unclear on the difference between precedence, associativity and evaluation order. I suspect that this confusion arises from the difference between how most people are trained to evaluate arithmetical expressions versus how compilers generate code to evaluate arithmetical expressions. As a child it was drilled into me that the way to evaluate an arithmetica ...

[ read more ]

Wednesday, May 21, 2008

Method Hiding Apologia

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

Here's some back-and-forth from an email conversation I had with a user a while back. Why should one avoid method hiding?  If there were no advantages and only disadvantages then we would not have added it to the language in the first place. C# implements hiding because hiding is frequently useful.   I therefore deny the premise of the question. One should not avoid method hiding if it is the right thing to do. But I find method hiding confusing. It lets derived types appear to ...

[ read more ]

Monday, May 19, 2008

A Generic Constraint Question

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

Here's a question I get fairly frequently: the user desires to create a generic type Bar<T> constrained such that T is guaranteed to be a Foo<U>, for some U. The way they usually try to write this is class Bar<T>  where T : Foo<T> {... which of course then does not work. The user discovers this when they type  new Bar<Foo<string>>() and get an error stating that the constraint has been violated. Which it certainly has. The constraint says that T m ...

[ read more ]

Wednesday, May 14, 2008

Mutating Readonly Structs

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

Consider this program which attempts to mutate a readonly mutable struct. What happens? struct Mutable {    private int x;    public int Mutate() {        this.x = this.x + 1;        return this.x;    }} class Test {    public readonly Mutable m = new Mutable();    static void Main(string[] args) {        Te ...

[ read more ]

Monday, May 12, 2008

Trivial Projections Are (Usually) Optimized Away

by Eric Lippert via Fabulous Adventures In Coding on 5/12/2008 1:57:00 PM

OK, computers aren't entirely dumb when it comes to LINQ. Here's an example of a place where we're a bit smarter. Consider the following query: IEnumerable<int> query = from n in number_array orderby n select n; Does this get transformed by the compiler into IEnumerable<int> query = number_array.OrderBy(n => n); or IEnumerable<int> query = number_array.OrderBy(n => n).Select( n => n ); ? This question caused tremendous debate amongst the members of the C# design and i ...

[ read more ]

Friday, May 09, 2008

Computers are dumb

by Eric Lippert via Fabulous Adventures In Coding on 5/9/2008 3:20:00 PM

  A few short takes today, from questions I've received recently about LINQ in C# 3.0. The first question was "in the following code, does it really check every single non-negative integer, or does it use the knowledge that once you're beyond ten, you can stop iterating?" var smallNumbers = Enumerable.Range(0, int.MaxValue).Where(n => n < 10);foreach (int i in smallNumbers)    Console.WriteLine(i);The former. You asked LINQ to Objects to apply a predicate to a sequence ...

[ read more ]

Friday, May 02, 2008

Protected Member Access, Part Four

by Eric Lippert via Fabulous Adventures In Coding on 5/2/2008 4:13:50 PM

In Part Two I asked a couple of follow-up questions, the first of which was: Suppose you were a hostile third party and you wanted to mess up the parenting invariant. Clearly, if you are sufficiently trusted, you can always use private reflection or unsafe code to muck around with the state directly, so that's not a very interesting attack. Any other bright ideas come to mind for ways that this code is vulnerable to tampering? Before I get into some ideas for attacks, I want to re-emphasize t ...

[ read more ]

Thursday, April 24, 2008

Why Can't I Access A Protected Member From A Derived Class, Part Three

by Eric Lippert via Fabulous Adventures In Coding on 4/24/2008 4:46:48 PM

Holy goodness, I've been busy. The MVP Summit was fabulous for us; thanks to all who attended and gave us great feedback on our ideas for evolving the languages and tools. And I've been doing some longer-lead thinking and working on language futures, which I will blog about at a later date. Last time I promised another oddity of "protected" semantics. An issue that I get asked about all the time involves the meaning of this code: namespace Foo {  public class Base {    prot ...

[ read more ]

Friday, March 28, 2008

Why Can't I Access A Protected Member From A Derived Class, Part Two: Why Can I?

by Eric Lippert via Fabulous Adventures In Coding on 3/28/2008 11:30:43 PM

This is a follow-up to my 2005 post on the same subject  which I believe sets a personal record for the longest time between parts of a series. (Of course, I didn't know it was a series when I started it.) Please read the previous article in this series, as this post assumes knowledge of part one. ....... OK, now that you've read that, it's clear why you can only access a protected member from an instance of an object known to be of a type at least as derived as the current context. You ca ...

[ read more ]

Monday, February 18, 2008

Why Do Initializers Run In The Opposite Order As Constructors? Part Two

by Eric Lippert via Fabulous Adventures In Coding on 2/18/2008 3:25:12 PM

As you might have figured out, the answer to last week's puzzle is "if the constructors and initializers run in their actual order then an initialized readonly field of reference type is guaranteed to be non null in any possible call. That guarantee cannot be met if the initializers run in the expected order." Suppose counterfactually that initializers ran in the expected order, that is, derived class initializers run after the base class constructor body. Consider the following pathological ca ...

[ read more ]

Friday, February 15, 2008

Why Do Initializers Run In The Opposite Order As Constructors? Part One

by Eric Lippert via Fabulous Adventures In Coding on 2/15/2008 11:01:41 PM

Pop quiz! What do you expect the output of this program to be?   using System; class Foo{    public Foo(string s)    {        Console.WriteLine("Foo constructor: {0}", s);    }    public void Bar() { }} class Base{    readonly Foo baseFoo = new Foo("Base initializer");    public Base()    {        Console.WriteLine ...

[ read more ]

Tuesday, February 12, 2008

Immutability in C# Part Eleven: A working double-ended queue

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

At long last, let's get to that double-ended queue. Sorry for leaving you in suspense! Last time we came up with a non-solution -- as commenters immediately discovered, the given algorithm and data structure are deeply inefficient.  However, the basic idea is sound. There are a number of ways to solve this problem, but the way I'm going to talk about today is a much more efficient variation on the theme of our previous unsuccessful attempt. That is, have cheap access to the endpoints, and ...

[ read more ]

Tuesday, January 22, 2008

Immutability in C# Part 10: A double-ended queue

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

Based on the comments, the implementation of a single-ended queue as two stacks was somewhat mind-blowing for a number of readers. People, you ain't seen nothing yet. Before we get into the actual bits and bytes of the solution, think for a bit about how you might implement an immutable queue which could act like both a stack or a queue at any time. You can think of a stack as "it goes on the left end, it comes off the left end", and a queue as "it goes on the left end, it comes off the right e ...

[ read more ]

Immutability in C# Part Nine: Academic? Plus my AVL tree implementation

by Eric Lippert via Fabulous Adventures In Coding on 1/22/2008 12:13:12 AM

Good Monday morning all. I have received a lot of good comments on this series so far that I thought I would speak to a bit. Academic? First and foremost, a number of people have asked questions which could be summed up as "isn't this just an academic exercise? I have a job to do here!" No, I do not believe that it is just an academic exercise, not at all. When I compare the practical, solving-real-problems code I write using immutable or ("mostly" immutable objects) to that which uses highly m ...

[ read more ]

Friday, January 18, 2008

Immutability in C# Part Eight: Even More On Binary Trees

by Eric Lippert via Fabulous Adventures In Coding on 1/18/2008 7:02:13 PM

Last year we declared a relatively simple interface to represent an immutable binary tree. We noticed that it was different from every other interface that we've declared so far, in that it really said nothing at all about the immutability of the tree. One normally thinks of immutable data types not in terms of their shape, but rather in terms of what operations may be performed on the data type. Operations are usually either to query the object somehow, or to "modify" it by producing new modif ...

[ read more ]

Wednesday, December 19, 2007

Immutability in C# Part Seven: More on Binary Trees

by Eric Lippert via Fabulous Adventures In Coding on 12/19/2007 8:01:00 PM

Lots of good comments on my previous post. To briefly follow up: One of the downsides of immutable tree implementations is that usually the tree must be built from the leaves up, which is not always convenient. We'll look at implementations which hide this fact from the user in future posts. One smartypants pointed out that sure, this tree can have cycles -- if you have another binary tree implementation that has cycles and then paste such a cyclic tree in. True; what I meant was that using ...

[ read more ]

Tuesday, December 18, 2007

Immutability in C# Part Six: A Simple Binary Tree

by Eric Lippert via Fabulous Adventures In Coding on 12/18/2007 7:30:00 PM

OK, we've gotten pretty good at this by now. A straightforward implementation of an immutable generic binary tree requires little comment on the basics. A binary tree is either empty, or a value, left tree and right tree: public interface IBinaryTree<V>{    bool IsEmpty { get; }    V Value { get; }    IBinaryTree<V> Left { get; }    IBinaryTree<V> Right { get; }} And our implementation has, as always, a singleton emp ...

[ read more ]

Monday, December 10, 2007

Immutability in C# Part Four: An Immutable Queue

by Eric Lippert via Fabulous Adventures In Coding on 12/10/2007 3:04:00 PM

An immutable queue is a bit trickier than an immutable stack, but we’re tough, we can handle it. First off, the interface is straightforward; enqueuing or dequeuing results in a new queue:     public interface IQueue<T> : IEnumerable<T>    {        bool IsEmpty { get; }        T Peek();        IQueue<T> Enqueue(T value);     ...

[ read more ]

Thursday, December 06, 2007

Immutability in C# Part Three: A Covariant Immutable Stack

by Eric Lippert via Fabulous Adventures In Coding on 12/6/2007 3:55:00 PM

Now suppose we had a hypothetical future version of C# in which interface covariance worked, and we wanted a covariant immutable stack. That is, we want to be able to implicitly convert an IStack<Giraffe> to IStack<Mammal>. As we've already discussed, this doesn't make much sense in an array, even though doing so is legal in C# today. If you cast a Giraffe[] to Mammal[] then you can try to put a Tiger into the Mammal[] and it will fail at run time. It seems like the same should be t ...

[ read more ]

Tuesday, December 04, 2007

Immutability in C# Part Two: A Simple Immutable Stack

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

Let’s start with something simple: an immutable stack. Now, immediately I hear the objection: a stack is by its very nature something that changes. A stack is an abstract data type with the interface void Push(T t);T Pop();bool IsEmpty { get; } You push stuff onto it, you pop stuff off of it, it changes. How can it be immutable? Every time you need to make a data structure immutable, you use basically the same trick: an operation which “changes” the data structure does so by constructing a new ...

[ read more ]

Tuesday, November 13, 2007

Immutability in C# Part One: Kinds of Immutability

by Eric Lippert via Fabulous Adventures In Coding on 11/13/2007 5:56:00 PM

I said in an earlier post that I believe that immutable objects are the way of the future in C#. I stand by that statement while at the same time noting that it is at this point sufficiently vague as to be practically meaningless! “Immutable” means different things to different people; different kinds of immutability have different pros and cons. I’d like to spend some time over the next few weeks talking about possible directions that C# could go to improve the developer experience when writin ...

[ read more ]

Monday, November 05, 2007

C# 3.0 Return Type Inference Does Not Work On Method Groups

by Eric Lippert via Fabulous Adventures In Coding on 11/5/2007 6:48:00 PM

Thanks all for your excellent feedback on my variance series. I am still reading and digesting the feedback and I shall take it to the language design committee later this month. Returning to less hypothetical but equally complicated issues, today, what I thought would be a rather obscure issue with C# 3.0 type inference which multiple people have reported to me since the last beta. Perhaps it is not as obscure as I thought! Consider this (contrived, but simplified from real code) example ...

[ read more ]

Subscribe

New Feed

Product Spotlight

Recently Updated Sources

Legal Note

The content of the postings is owned by the respective author. CSharpFeeds is not responsible for the contents of the postings. This site is automatically generated and cannot be reviewed for abusive content. If you find abusive content on CSharpFeeds, please contact us. Designated trademarks and brands are the property of their respective owners. All rights reserved.

Advertise with us