- How can we create an immutable data structure which represents
*a directed graph with labels on the edges*? - Given a directed acyclic graph (DAG),
*what are all the possible*?**edge**traversals through that graph starting from a particular node

First things first. Like I said, there are a zillion different ways to represent a graph. I want to do so immutably — again, an immutable data type is one where “mutations” return a new object that is a mutated version of the original object, which stays the same. For my purposes today, I want to be able to take an existing graph, possibly empty, and insert new nodes and edges into that graph. The data structure I’m going to choose for my internal representation is that a graph consists of:

- an unordered, no-duplicates set of nodes of arbitrary type
- every node has an unordered, no-duplicates set of outgoing edges of arbitrary type
- an edge that leaves one node in a graph goes to another (or the same) node in the graph

Note that this implies that there can be two edges that both leave node A and arrive at node B, so long as the values of the edges are different. But there cannot be two edges with the same value that both leave A and go to B and C.

With that set of characteristics in mind, we quickly realize that we could say that an immutable directed graph is nothing more than an immutable dictionary, where the keys are nodes and the values are themselves immutable dictionaries where the keys are edges and the values are the destination nodes of the edges.

Rather than making my own immutable dictionary — because that’s not the point of this series — I’ll just use the System.Collections.Immutable package downloadable from NuGet to define my graph. Since this is first, just a super-thin wrapper around a dictionary reference, and second, logically a value, I’ll make it a struct.

using System; using System.Collections.Generic; using System.Collections.Immutable; struct ImmutableDirectedGraph<N, E> { public readonly static ImmutableDirectedGraph<N, E> Empty = new ImmutableDirectedGraph<N, E>( ImmutableDictionary<N, ImmutableDictionary<E, N>>.Empty); private ImmutableDictionary<N, ImmutableDictionary<E, N>> graph; private ImmutableDirectedGraph( ImmutableDictionary<N, ImmutableDictionary<E, N>> graph) { this.graph = graph; }

To add a new node to the graph we first check to see if the graph already contains this node; if it does, we leave it alone. If not, we add it to the map with an empty set of outgoing edges.

public ImmutableDirectedGraph<N, E> AddNode(N node) { if (graph.ContainsKey(node)) return this; return new ImmutableDirectedGraph<N, E>( graph.Add(node, ImmutableDictionary<E, N>.Empty)); }

To add an edge to the graph, we first make sure that both nodes are in the graph. Once that’s taken care of, we get the edge set for the start node and add to it the new edge.

public ImmutableDirectedGraph<N, E> AddEdge(N start, N finish, E edge) { var g = this.AddNode(start).AddNode(finish); return new ImmutableDirectedGraph<N, E>( g.graph.SetItem( start, g.graph[start].SetItem(edge, finish)))); }

Remember, setting an item on an immutable dictionary gives you back a different dictionary with the new item added.

Finally, given a graph and a node, what are the outgoing edges? We could give an error if the node is not even in the graph, but I think it is reasonable to say that the edge set of a node that is not in the graph is the empty set:

public IReadOnlyDictionary<E, N> Edges(N node) { return graph.ContainsKey(node) ? graph[node] : ImmutableDictionary<E,N>.Empty; }

I’m not going to need edge and node removal for my purposes; doing so is left as an exercise to the reader. Note that the data structure I’ve sketched out here does not have an efficient mechanism for removing the edges that are pointing to a removed node; modifying the data structure to make that efficient is an interesting challenge that I’m not going to get into in this series.

As you’ve likely come to expect, to use this thing we start with the empty graph and add edges (and, if we like, nodes with no edges).

Here is a portion of the Zork map where I’ve removed a whole bunch of edges to make a DAG. (Click for larger.)

We can build that map in our graph structure like this:

var map = ImmutableDirectedGraph<string, string>.Empty .AddEdge("Troll Room", "East West Passage", "East") .AddEdge("East West Passage", "Round Room", "East") .AddEdge("East West Passage", "Chasm", "North") .AddEdge("Round Room", "North South Passage", "North") .AddEdge("Round Room", "Loud Room", "East") .AddEdge("Chasm", "Reservoir South", "Northeast") .AddEdge("North South Passage", "Chasm", "North") .AddEdge("North South Passage", "Deep Canyon", "Northeast") .AddEdge("Loud Room", "Deep Canyon", "Up") .AddEdge("Reservoir South", "Dam", "East") .AddEdge("Deep Canyon", "Reservoir South", "Northwest") .AddEdge("Dam", "Dam Lobby", "North") .AddEdge("Dam Lobby", "Maintenance Room", "East") .AddEdge("Dam Lobby", "Maintenance Room", "North");

Notice how there are two paths from the Dam Lobby to the Maintenance room, but our data structure handles that just fine.

**Next time:** we’ll see how to find all the traversals through that graph from the Troll Room to the Maintenance Room.

]]>

`{50, 60, 70, 80, 90}`

had combinations of exactly three elements as follows:
{ // 50, 60, 70, 80, 90 {50, 60, 70}, // T T T F F {50, 60, 80}, // T T F T F {50, 60, 90}, // T T F F T {50, 70, 80}, // T F T T F {50, 70, 90}, // T F T F T {50, 80, 90}, // T F F T T {60, 70, 80}, // F T T T F {60, 70, 90}, // F T T F T {60, 80, 90}, // F T F T T {70, 80, 90} // F F T T T }

The table of bits on the right hand side is true if the element is included in the combination and false if it is not. We recursively divided finding all combinations of a particular size up into two sub-problems: first we enumerated all the cases where the left bit was true, and then all the cases where the left bit was false. We used that insight to recursively construct every sequence of n Booleans where there were exactly k true values.

If you treat the chart above as bits in an integer with the least-significant bit on the right, we have the values 28, 26, 25, 22, 21, 19, 14, 13, 11, 7 — that is, we have produced the sequence in order of descending value when interpreted as bits this way.

I have in mind a slightly different order. What if we treated those Booleans as bits in an integer with the least-significant bit on the *left*, and then re-ordered them into *ascending* order by integer value? Here I’ve reversed the bits left-to-right in the chart, and reordered the rows into ascending order by bit value:

{ // 90, 80, 70, 60, 50 {50, 60, 70}, // F F T T T {50, 60, 80}, // F T F T T {50, 70, 80}, // F T T F T {60, 70, 80}, // F T T T F {50, 60, 90}, // T F F T T {50, 70, 90}, // T F T F T {60, 70, 90}, // T F T T F {50, 80, 90}, // T T F F T {60, 80, 90}, // T T F T F {70, 80, 90} // T T T F F }

You’ll note that this order is very similar but not identical to our previous ordering.

Suppose we treat these not as sequences of bits, but as sets of bit numbers, where the low bit is bit zero, the next is bit one, and so on up to bit four:

{ {50, 60, 70}, // 2 1 0 {50, 60, 80}, // 3 1 0 {50, 70, 80}, // 3 2 0 {60, 70, 80}, // 3 2 1 {50, 60, 90}, // 4 1 0 {50, 70, 90}, // 4 2 0 {60, 70, 90}, // 4 2 1 {50, 80, 90}, // 4 3 0 {60, 80, 90}, // 4 3 1 {70, 80, 90} // 4 3 2 }

Previously we noted that the job of producing all combinations is equivalent to producing all bit sequences with a given number of true bits; well, *that* is in turn equivalent to producing *all sets of integers with a given number of elements and a certain bound*. In this case, all the sets of integers that have exactly three elements, and are between zero and four inclusive. Moreover, the integers are indexes into the original sequence!

Let’s make a recursive method to produce these bit sets. The recursion is a pretty straightforward modification of our previous algorithm:

// Takes integers n and k, both non-negative. // Produces all sets of exactly k elements consisting only of // integers from 0 through n - 1. private static IEnumerable<TinySet> Combinations(int n, int k) { // Base case: if k is zero then there can be only one set // regardless of the value of n: the empty set is the only set // with zero elements. if (k == 0) { yield return TinySet.Empty; yield break; } // Base case: if n < k then there can be no set of exactly // k elements containing values from 0 to n - 1, because sets // do not contain repeated elements. if (n < k) yield break; // A set containing k elements where each is an integer from // 0 to n - 2 is also a set of k elements where each is an // integer from 0 to n - 1, so yield all of those. foreach(var r in Combinations(n-1, k)) yield return r; // If we add n - 1 to all the sets of k - 1 elements where each // is an integer from 0 to n - 2, then we get a set of k elements // where each is an integer from 0 to n - 1. foreach(var r in Combinations(n-1, k-1)) yield return r.Add(n-1); }

Previously we produced a sequence of bools indicating whether a particular item has been chosen or not. Now we have a sequence of indicies, so it seems reasonable to require an indexed collection. Writing the code to deal efficiently with a non-indexed sequence is left as an exercise.

public static IEnumerable<IEnumerable<T>> Combinations<T>( this IList<T> items, int k) { if (k < 0) throw new InvalidOperationException(); if (items == null) throw new ArgumentNullException("items"); int n = items.Count; if (n > TinySet.Maximum) throw new InvalidOperationException(); return from combination in Combinations(n, k) select (from index in combination select items[index]); }

We can then run this just as we did before:

var sequence = new[] { 50, 60, 70, 80, 90 }; foreach(var combination in sequence.Combinations(3)) Console.WriteLine(string.Join(",", combination));

And get, as we expect:

50,60,70 50,60,80 50,70,80 60,70,80 50,60,90 50,70,90 60,70,90 50,80,90 60,80,90 70,80,90

Notice how this is in a slightly different order than our original algorithm. The original algorithm produced everything that contained 50 first; this algorithm produces everything that contains 90 last.

**Next time on FAIC:** We’ll keep exploring recursive algorithms that use stacks, but this time we’ll solve a problem on graphs.

]]>

I’ve put a pair of binoculars facing the sun on my desk on a notebook, masked one of the lenses with a post-it note, and propped it up with a box of business cards. By rotating the notebook I can follow the sun, and by rotating the corner of the box on the left side and keeping the corner on the right side fixed, I can very slightly adjust the height. Since the sun moves left-to-right much faster than up-and-down at 1:40 in the afternoon, that’s handy. I then focus the image on the wall.

I’ll keep posting images as the eclipse continues this afternoon, as long as those clouds hold back!

UPDATE: It begins! The blurry dark bit is a sunspot.

UPDATE: NOOOOOOO

That’s a big cloud. This might be done just as it was getting started. Vexing!

UPDATE:YAAAAAY!

The sun peeked out a few minutes before maximum eclipse, and then disappeared again:

For comparison, here’s an image from the Griffith Observatory shot at the same time:

This image shot through a telescope is of course inverted compared to mine shot with binoculars. Notice that the sunspot that is just a blur in my images is sharp here. Also, since Los Angeles is quite a ways south of Seattle, the percentage of the sun’s disk covered at maximum eclipse is quite different.

And of course, ten minutes after the eclipse ended the sun came out in the most dramatic possible fashion:

while it was still pouring rain in the east:

I picked the wrong day to leave my good camera at home!

]]>

Now, on the one hand, who the heck cares whether we use 4 bytes per bit stack or 400 for this problem? The lowest common denominator 32 bit machine has two billion bytes of address space, and it seems unlikely that the difference between success and failure in the market is going to be the difference between 4 bytes and 400 bytes.

On the other hand, representing a combination in a single int is an interesting challenge and lets me demonstrate a nice variant of the algorithm I presented last time. (Incidentally, an alert reader pointed out a harmless but vexing bug in my algorithm of last time, which I have fixed; see the post for details.)

Last time we used an immutable stack of Booleans; this time we’re going to use an immutable set of integers. (Recall that a *set* is a collection which has no particular order imposed on its elements, and there are no duplicate elements.) Our immutable stack was designed so that pushing did not mutate the stack; rather, it produced a new stack with the pushed element on it. Similarly, our immutable set will have an “add” method that does not mutate the set; rather, it returns a new set with the item added. We’ll make this set a struct so that it really does consume no more memory than its single int field:

using System; using System.Collections; using System.Collections.Generic; using System.Linq; internal struct TinySet : IEnumerable<int> { public static readonly TinySet Empty = new TinySet(0); public const int Minimum = 0; public const int Maximum = 31; private readonly int bits; private TinySet(int bits) { this.bits = bits; } public bool Contains(int item) { if (item < Minimum || item > Maximum) return false; return (bits & (1 << item)) != 0; } public TinySet Add(int item) { if (item < Minimum || item > Maximum) throw new InvalidOperationException(); return new TinySet(bits | (1 << item)); } public TinySet Remove(int item) { if (item < Minimum || item > Maximum) return this; return new TinySet(bits & ~(1 << item)); } IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); } public IEnumerator<int> GetEnumerator() { for(int item = Minimum; item <= Maximum; ++item) if (Contains(item)) yield return item; } }

Long time readers will recognize this as the same tiny set I used in my series on graph colouring. We’re not going to need removal but I added it anyways just for the heck of it. Adding other features like union, intersection, and so on, is easily done and left for the reader.

We can then use this set the same way we used our stack; the code

TinySet mySet = TinySet.Empty.Add(1).Add(0).Add(3);

produces the set `{0, 1, 3}`

.

**Next time:** Now that we have this data structure we can modify our algorithm of last time to produce all the combinations.

]]>

- Is the problem trivial? If so, solve it.
- Otherwise, break the problem down into one or more smaller problems, solve them recursively, and aggregate those solutions into the solution of the larger problem

Let’s start with a signature. What do we have? integers n and k. What do we want? A sequence of Boolean stacks such that the size is n, and there are k bits turned on. We therefore require that n and k both be non-negative, and that n be greater than or equal to k.

private static IEnumerable<ImmutableStack<bool>> Combinations (int n, int k) {

**UPDATE: A commenter noted that though my program worked, the private helper method did not actually fulfill its contract, and its caller was therefore “working by accident”. Apologies for the error; I’ve fixed it.**

What is the trivial case? If we are trying to make a sequence of zero bits, with zero of them on, there is only one possibility, which is the empty sequence. And we know that if n is smaller than k, then we are trying to make a sequence with n bits that has more than all of them true, which is impossible, so that sequence is empty. Those sound pretty trivial! Since this is a private method we can eschew the error checking; the caller will be responsible for ensuring that the arguments are non-negative.

if (k == 0 && n == 0) { yield return ImmutableStack<bool>.Empty; yield break; } if (n < k) yield break;

We need to break the problem down into smaller problems. Let’s go back to our original chart from part one for inspiration:

{ // 50, 60, 70, 80, 90 {50, 60, 70}, // T T T F F {50, 60, 80}, // T T F T F {50, 60, 90}, // T T F F T {50, 70, 80}, // T F T T F {50, 70, 90}, // T F T F T {50, 80, 90}, // T F F T T ---------- {60, 70, 80}, // F T T T F {60, 70, 90}, // F T T F T {60, 80, 90}, // F T F T T {70, 80, 90} // F F T T T }

I’ve divided that into two parts based on whether the first element is true or false. Being able to find the point where you “divide and conquer” is the key to a lot of recursive algorithms, and this seems like a good spot to do it. For the cases where the first element is true, the remaining four elements have to be from the sequences of four Booleans where exactly two are true. For the cases where the first element is false, the remaining four elements have to be from the sequences of four Booleans where exactly three are true. In both cases we’ve decreased the size of the sequence and are therefore heading rapidly towards our recursive base case. We can now easily write the rest of the algorithm based on this insight:

if (k > 0) foreach(var r in Combinations(n-1, k-1)) yield return r.Push(true); foreach(var r in Combinations(n-1, k)) yield return r.Push(false); }

(Do you see why we don’t need to check whether n > 0 in either recursive case?)

We’ve solved an equivalent problem of the original problem given; the original problem was to produce combinations of a sequence, not bits. Let’s actually solve that problem, shall we? We need a combination of the `Zip`

and `Where`

extension methods on sequences, which is easily written: (Error handling omitted again.)

private static IEnumerable<T> ZipWhere<T>( this IEnumerable<T> items, IEnumerable<bool> selectors) { using (var e1 = items.GetEnumerator()) using (var e2 = selectors.GetEnumerator()) while (e1.MoveNext() && e2.MoveNext()) if (e2.Current) yield return e1.Current; }

And now, finally we have enough gear to solve the original problem:

public static IEnumerable<IEnumerable<T>> Combinations<T>( this IEnumerable<T> items, int k) { if (k < 0) throw new InvalidOperationException(); return from combination in Combinations(items.Count(), k) select items.ZipWhere(combination); }

And now we can use our new method:

var sequence = new[] { 50, 60, 70, 80, 90 }; foreach(var combination in sequence.Combinations(3)) Console.WriteLine(string.Join(",", combination

and as we expect, we get

50,60,70 50,60,80 50,60,90 50,70,80 50,70,90 50,80,90 60,70,80 60,70,90 60,80,90 70,80,90

All the code put together in runnable form with proper error handling is here.

**Next time: **we’ll take a similar but different approach to solving the same problem, just for the heck of it.

]]>

An approach that I often see is “enumerate all sequences of n Booleans, count the number of on bits, and discard those which have too many or too few”. Though that works, it’s not ideal. Suppose we are seeking to enumerate the combinations of 16 items chosen from a set of 32. There are over four billion possible combinations of 32 bits, and of those over three billion of them have more or fewer than 16 true bits, so that’s a lot of counting and discarding to do. We can do better! To do so, we’ll use a combination of all my favourite techniques:

- Immutable data structures
- Abstract classes with derived nested classes
- Recursion

Long-time readers of this blog will have seen me use these techniques before, but for new readers, a quick introduction is in order.

The idea of an immutable collection is that the collection does not change when you add or remove something from it. That seems contradictory, but really it makes a lot of sense. The number 3 does not change into 7 when you add 4 to it; the number 3 is eternal and unchanging. Rather, adding 4 to it produces a new, entirely different number called 7. Similarly, adding an item to a collection does not change the original collection; it produces a new collection.

That might sound inefficient, but actually it is very efficient: *because the original collection is immutable, we can use all or some of the original collection data structure in the new data structure*.

The data structure I need to solve this problem is an *immutable stack of Booleans*, so let’s whip one of those up. (Of course we could use data structures in the BCL immutable collections, but for pedagogic and amusement purposes, let’s just make our own.) The operations I’m going to need are just pushing and enumerating, but for completeness let’s add public members for popping and emptiness checking as well. I’ll use one of my favourite techniques of an abstract base class whose derived classes are nested within it:

using System; using System.Collections; using System.Collections.Generic; abstract class ImmutableStack<T>: IEnumerable<T> { public static readonly ImmutableStack<T> Empty = new EmptyStack(); private ImmutableStack() {} public abstract ImmutableStack<T> Pop(); public abstract T Top { get; } public abstract bool IsEmpty { get; } public IEnumerator<T> GetEnumerator() { var current = this; while(!current.IsEmpty) { yield return current.Top; current = current.Pop(); } } IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); } public ImmutableStack<T> Push(T value) { return new NonEmptyStack(value, this); } private class EmptyStack: ImmutableStack<T> { public override ImmutableStack<T> Pop() { throw new InvalidOperationException(); } public override T Top { get { throw new InvalidOperationException(); } } public override bool IsEmpty { get { return true; } } } private class NonEmptyStack : ImmutableStack<T> { private readonly T head; private readonly ImmutableStack<T> tail; public NonEmptyStack(T head, ImmutableStack<T> tail) { this.head = head; this.tail = tail; } public override ImmutableStack<T> Pop() { return this.tail; } public override T Top { get { return this.head; } } public override bool IsEmpty { get { return false; } } } }

We can create one of these like this:

ImmutableStack<bool> myStack = ImmutableStack<bool>.Empty .Push(true) .Push(false) .Push(false);

And hey, now we’ve got the stack `false, false, true`

. Again, remember, pushing on `Empty`

did not change Empty at all. It’s the same as it ever was.

Our technique is going to be to recursively build longer bit sequences out of shorter bit sequences. Since pushing onto an immutable stack is cheap, and we don’t ever have to worry about the stack being changed by someone else, we’ll see that the algorithm is pretty straightforward.

**Next time:** Now that we have our helper class, we’ll actually enumerate the combinations.

]]>

{ { 1, 2 }, { 10, 11, 12} }

and produce the sequence of all possible sequences that take one element from each of the original sequences. That would be:

{ {1, 10}, {1, 11}, {1, 12}, {2, 10}, {2, 11}, {2, 12} }

in this case. The permutations of a sequence, say, `{20, 30, 40}`

are all the different ways to reorder that sequence:

{ {20, 30, 40}, {20, 40, 30}, {30, 20, 40}, {30, 40, 20}, {40, 20, 30}, {40, 30, 20} }

Today I want to talk about a problem I’ve never covered, which is how to generate all the *combinations* of a sequence. The combinations are *all the ways to take some given number of elements from the sequence*. Or, equivalently, *all the subsequences of a given length*. (A *subsequence *of a sequence has elements from the sequence in the same order, but some elements from the original sequence can be missing.) For example, if we have the sequence `{50, 60, 70, 80, 90}`

and we wish to choose three, then the combinations are:

{ {50, 60, 70}, {50, 60, 80}, {50, 60, 90}, {50, 70, 80}, {50, 70, 90}, {50, 80, 90}, {60, 70, 80}, {60, 70, 90}, {60, 80, 90}, {70, 80, 90} }

How many such subsequences are there? If there are n items in the original sequence and we are choosing k of those items then I will give you without proof or argument that the number of possible combinations is n!/k!(n-k)!. Let’s just double check that: we had five elements, we chose three of them, 5!/3!(5-3)! is in fact 10. This formula produces the binomial coefficient, and it has many interesting properties beyond those in combinatorics.

When writing computer programs it is wise to state the edge cases. Given the same sequence, *what if we wish to choose none of them*? There does exist a subsequence which has zero elements, so we should produce it; the answer would be `{ { } }`

. What if we have a sequence of five items and we wish to choose six of them? There is no way to do that; there is no six-element subsequence. So the answer should be `{ }`

, the empty sequence of sequences.

The first clever bit is to notice that essentially what we are doing in each subsequence is deciding whether or not to include each element from the sequence. Let’s lay out those subsequences again and indicate whether the corresponding member was included or not, true or false:

{ // 50, 60, 70, 80, 90 {50, 60, 70}, // T T T F F {50, 60, 80}, // T T F T F {50, 60, 90}, // T T F F T {50, 70, 80}, // T F T T F {50, 70, 90}, // T F T F T {50, 80, 90}, // T F F T T {60, 70, 80}, // F T T T F {60, 70, 90}, // F T T F T {60, 80, 90}, // F T F T T {70, 80, 90} // F F T T T }

Aha! If we can enumerate *all the sequences of n bits that have exactly k true *then we have solved our problem.

**Next time:** We’ll do just that.

]]>

Let’s go back to our original, simplest case: a local variable shadows another:

class C { static void M1() { int x2; { int x2; } }

Recall that the pre-Roslyn compiler gave the error on the inner `x2`

:

error CS0136: A local variable named 'x2' cannot be declared in this scope because it would give a different meaning to 'x2', which is already used in a 'parent or current' scope to denote something else

Roslyn will give the error (again, on the inner `x2`

)

error CS0136: A local or parameter named 'x2' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter

OMG so much better. I am still not thrilled with the “local or parameter” there; Roslyn knows which it was and could say so, but hey, this is so much more understandable that let’s not quibble. Note that the error still doesn’t say what we’re conflicting with, but what would be the point? We’re conflicting with another local or parameter, so all it would be able to say is “a local or parameter named ‘x2′” and we already know that. Note also that “enclosing” is not in quotes, and that’s because it is *always* the inner of the two conflicting definitions that gets the error. As I mentioned before, that is the one that is likely to need to change, so that’s where Roslyn should consistently report the error no matter whether the outer declaration is lexically before or after the inner one. The next most likely case is that a local conflicts with a member:

class C { static int x8; static void M9() { { int x8; } int x10 = x8; }

Recall that the pre-Roslyn compiler gives this awful error on the initialization of `x10`

:

error CS0135: 'x8' conflicts with the declaration 'C.x8'

Roslyn will give this error on the declaration of the inner local `x8`

:

error CS0135: A local, parameter or range variable named 'x8' cannot be declared in this scope because that name is used in an enclosing local scope to refer to 'C.x8'

Again, I am not thrilled with the “local, parameter or range variable”, but let’s not quibble; this sentence is actually understandable by mortal beings, it tells you what the conflict is, and it identifies the line that must change. Since I’ve reworded both CS0135 and CS0136 to refer specifically to locals, we now no longer have an error message for the rare case where a name has two meanings and neither is a local:

class C { static void x11(); class N { static int x11; static void M12() { x11(); int x13 = x11; } }

Again, the pre-Roslyn compiler produces

error CS0135: 'x11' conflicts with the declaration 'C.N.x11'

Roslyn will produce a new error:

error CS7039: 'x11' cannot be used in this local scope because that name has been used to refer to method 'C.x11()'

Identifying that the conflict is a method I thought was a nice touch. It would have been nice to also call out what the other `x11`

refers to; that would be a good feature for someone to add to Roslyn.

Finally, one more new error message for the case where the conflicting names are in different (but nested) scopes:

class C { static void x11(); class N { static int x11; static void M12() { x11(); { int x13 = x11; } } }

error CS7040: 'x11' cannot be used in this local scope because that name has been used in an enclosing scope to refer to method 'C.x11()'

I said that I’d be exploring this feature at absurd depth; surprisingly, there is still farther we could go here. The interaction of this feature with the “Color Color” feature — which has the opposite behavior of allowing simple name `Color`

to refer to both a type and a member — is quite interesting. But I think I will leave it here for now and come back to Color Color another day.

]]>

As always, if you have questions about a bug you’ve found in a C, C++, C# or Java program that you think would make a good episode of ATBG, please send your question along with a small reproducer of the problem to `TheBugGuys@Coverity.com`

. We cannot promise to answer every question or solve every problem, but we’ll take a selection of the best questions that we can answer and address them on the dev testing blog every couple of weeks.

]]>

The key to solving the riddle is a little-known rule about resolving a name from a set of possible class members:

if the member is invoked, all non-invocable members are removed from the set

And now we can see how to do it:

class C { static void x11() {} class N { static int x11; static void M12() { x11(); int x13 = x11; } }

The first usage of simple name `x11`

is invoked, so non-invocable member `C.N.x11`

is removed from the set of things to consider. But the second usage is not invoked and therefore the field is chosen. Now, you might say that hey, nothing terrible has happened here, but still, it is profoundly weird that `x11`

means two different things in the same block. It seems like this could be really, really confusing were the code not as straightforward and short as this. So this is illegal. And once again, we have the worst possible error message:

error CS0135: 'x11' conflicts with the declaration 'C.N.x11'

I exaggerate; I suppose it could be worse. It could say, as we saw CS0136 does last time:

error CS0135: 'x11' conflicts with something, but I'm not telling you what!

So I suppose we can be thankful for small mercies.

The challenge was also accidentally made somewhat more difficult because Visual Studio 14 CTP 3 does not correctly enforce the rule we’re discussing here. I’m not sure why; the version of Roslyn on codeplex does, and I would have thought CTP 3 would be using it. There has been some talk of modifying this rule; I’ll investigate!

**Next time:** a brief interlude for this week’s Ask The Bug Guys, and then we’ll have the thrilling conclusion of this series.

]]>