Click here to Skip to main content
15,891,513 members
Articles / Programming Languages / C#

The Curious Case of Any() and All()

Rate me:
Please Sign up or sign in to vote.
4.78/5 (15 votes)
2 Aug 2016CPOL3 min read 7.9K   5  
The importance of "All None of Them." Let’s discuss how this bit of set theory can make our lives as developers easier.

Last week, I posted a puzzle on twitter. Fill in the GetSpecialSequence() method such that Any() returns false, and All() returns true. Here’s the code from the puzzle:

C#
using static System.Console;
using System.Collections.Generic;
using System.Linq;

namespace AnyAndAll
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var sequence = GetSpecialSequence();

            // Prints "True"
            WriteLine(sequence.All(b => b == true));

            // Prints "False"
            WriteLine(sequence.Any(b => b == true));
        }

        private static IEnumerable<bool> GetSpecialSequence()
        {
            // Puzzle: What should this implementation be?
            return null;
        }
    }
}

The answer is simply to return the empty sequence:

C#
private static IEnumerable<bool> GetSpecialSequence()
{
    return Enumerable.Empty<bool>();
}

Let’s discuss why this is both important, and a good thing.

True for “All None of them”

Several developers on twitter did get the right answer to the puzzle. Many of those that did get the right answer also responded by saying how they disliked this behavior, and why it was confusing.

The behavior is correct if you understand set theory from mathematics:

  • Any() returns true when at least one item in the set satisfies the condition. It follows that the empty set always return false.
  • All() returns true when all of the items in the set satisfy the condition. It follows that the empty set always return true.

Let’s drill into that second statement: All 0 elements in the empty set satisfy the condition. Stated another way, there are no elements in the set that do not satisfy the condition.

The Importance of “All None of Them”

Let’s discuss how this bit of set theory can make our lives as developers easier.

If you know that a set of data always satisfies a condition, or is empty, we can often simplify the conditional branching in our code. In the C# spec meetings, it came up as a proposal for simplifying the rules around Definite Assignment. This code does not generate an error because it uses a variable before it has been assigned:

C#
int x;
if (false)
    WriteLine(x);

There are two rules in the existing spec that define this behavior. Paraphrasing, one says that a variable ‘v’ is definitely assigned at the beginning of any unreachable statement. The other (more complicated rule) says that v is definitely assigned if and only if v is definitely assigned on all control flow transfers that target the beginning of the statement.

Read it carefully with set theory in mind, and you see that the second rule makes the first rule redundant: if a variable is definitely assigned on all (none) of the control paths that target the statement, that variable is definitely assigned. We could remove similar redundancies in this section of the spec by finding other rules that effectively created an empty set of possible paths, and clearing them out.

Consider how this might apply in your work. If you can find logic in your code that finds data which satisfies a particular criteria and then branches based on that data. Can you simplify that code if the empty set code “just works” the same as other paths? Can you find other locations in code where “for all items” can work for the interesting case of “for all none of these items”?

I hope you enjoyed the puzzle. If you want another brain teaser, work out why this solution satisfies the original puzzle.

Hat tip to Neal Gafter for doing the work to simplify (and correct) the Definite Assignment section of the C# spec.

Hat tip to Evan Hauck for the most interesting solution to the puzzle.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect Bill Wagner Software LLC
United States United States
Bill Wagner is one of the world's foremost C# developers and a member of the ECMA C# Standards Committee. He is President of the Humanitarian Toolbox, has been awarded Microsoft Regional Director and .NET MVP for 10+years, and was recently appointed to the .NET Foundation Advisory Council. Wagner currently works with companies ranging from start-ups to enterprises improving the software development process and growing their software development teams.

Comments and Discussions

 
-- There are no messages in this forum --