-1

The other day I read the following two blog posts:

Raymond Chen, Closing over the loop variable is just as harmful in JavaScript as it is in C#, and more cumbersome to fix

Eric Lippert, Closing over the loop variable considered harmful

The basic summary of these two posts is that closing over the loop variable, rather than the loop value, is a language feature in both C# and JavaScript that is confusing and can cause significant and puzzling bugs.

That in mind, I was reading some MSDN documentation today on the use of generics, and I came across some code that confuses me greatly. Here is the code:

class TestGenericList
{
    static void Main()
    {
        // int is the type argument
        GenericList<int> list = new GenericList<int>();

        for (int x = 0; x < 10; x++)
        {
            list.AddHead(x);
        }

        foreach (int i in list)
        {
            System.Console.Write(i + " ");
        }
    }
}

This code bears a superficial resemblance to the code in the linked blog posts. Obviously this code outputs {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} and not {10, 10, 10, 10, 10, 10, 10, 10, 10}. Can anyone explain to me why this code is not a closure?

Lincoln Bergeson
  • 3,301
  • 5
  • 36
  • 53
  • 13
    Because no variables are captured in that code? There is no closure whatsoever. – Frédéric Hamidi Jun 13 '14 at 14:57
  • 2
    In addition, if the loop variable was closed over, the result would be `{ 10, 10, 10, 10, 10, 10, 10, 10, 10 }` not `{ 9, 9, 9, 9, 9, 9, 9, 9, 9 }`. – Frédéric Hamidi Jun 13 '14 at 15:01
  • If you would like to see look variable capture in action, [here is a link](http://ideone.com/v6hQtp). The code prints `6` three times, instead of printing `3`, `4`, `5` as one would expect. – Sergey Kalinichenko Jun 13 '14 at 15:03
  • See [Why is it bad to use an iteration variable in a lambda expression](http://stackoverflow.com/questions/227820/why-is-it-bad-to-use-an-iteration-variable-in-a-lambda-expression). – CodeCaster Jun 13 '14 at 15:04
  • @FrédéricHamidi could you please explain what you mean? I'm unclear on what exactly a closure is, and how variables are captured. – Lincoln Bergeson Jun 13 '14 at 15:14
  • @Lincoln, that would be redundant, your question is already addressed [here](http://stackoverflow.com/q/428617/464709). – Frédéric Hamidi Jun 13 '14 at 15:16
  • @FrédéricHamidi So there is no closure here because there is no function? – Lincoln Bergeson Jun 13 '14 at 15:17
  • 4
    This question is not off-topic. Many beginner programmers are justifiably confused about when an identifier which identifies a *variable* produces *the variable* or produces *the value of the variable*. This is such a case. When a variable is *read* from, the result is its *value*, so `AddHead(x)` adds the *current value* of `x` to the list, not *a reference to the variable `x`* to the list. – Eric Lippert Jun 13 '14 at 16:05
  • 2
    The key point is that *a lambda which reads a variable* is different than *a read of the variable*. When a lambda is created that reads a variable, the lambda when executed reads the current value of the variable, just like any other read reads the current value of the variable. The creation of the lambda does not read the variable and store the read value somewhere. – Eric Lippert Jun 13 '14 at 16:07
  • 1
    @LincolnBergeson: I mean I think that it's unlikely to be useful to future visitors with the way it is phrased (particularly with the somewhat hostile title). I suspect you could edit it to be more useful, possibly showing two sample loops and asking why one is capturing the variable and the other is not. – Jon Skeet Jun 13 '14 at 16:17
  • (I'm happy to have a go at editing it in such a way should you wish. And in retrospect, my close vote probably *was* a bit hasty. I blame my human reaction to hostile subject lines.) – Jon Skeet Jun 13 '14 at 16:52
  • @CodeCaster Here was my reasoning: I saw some code from Eric and Raymond that makes me wary of loops and variable capturing. A day passes. I see some code that superficially resembles the aforementioned code. Being a beginning programmer, I become confused. I turn to Stack Overflow for an explanation. My question is shot to hell because I do not understand the concept of a closure. I reopen my question because I would like to know what's going on in the MSDN sample code. That is all. – Lincoln Bergeson Jun 13 '14 at 18:03
  • The only connection between the code listings is that they have a `for` loop, is that where your confusion lies? A `for` loop is not called a closure. – CodeCaster Jun 13 '14 at 18:04
  • 1
    Yeah. They both have a for loop, they both seem to be assigning variables to thing, etc. I actually understand what's going on now, maybe I'll write up an answer myself. – Lincoln Bergeson Jun 13 '14 at 18:06
  • 1
    This question seems to demonstrate a clear lack of research. Simply doing a web search on the term "closure" would very clearly answer your question. – Servy Jun 13 '14 at 18:13

1 Answers1

1

My confusion and resulting question had mostly to do with the fact that I did not understand closures.

The only connection between the code listings is the for loop, which set off an alarm in my head. This, however, is not a closure at all, and as such has none of the pitfalls outlined in the two blog posts. A closure is something completely different, with a different set of potential problems.

Here is a link that teaches the concept of a closure.

Community
  • 1
  • 1
Lincoln Bergeson
  • 3,301
  • 5
  • 36
  • 53