1. 40

  2. 11

    This seems like a great change to address a very common Go pitfall.

    1. 7

      The rationale for the current behavior of re-using the loop variable was always performance. The claim was that allocating a new value for each iteration of a loop was costly enough to out-weigh the various points of confusion that are described in the link. So I would expect that a proposal to change this behavior would include a pretty thorough analysis of the performance impact. But on the subject of performance, the design document says only the following:

      In a very frequently executed already-correct loop, the new allocations may be unnecessary and could potentially cause more garbage collector pressure and a measurable performance difference. If so, standard monitoring and allocation profiles (pprof –alloc_objects) should pinpoint the location easily, and the fix is trivial: declare the variable above the loop.

      To be clear, I’m not against the change! I would just expect to see a much more rigorous analysis of the performance impact than this somewhat hand-wavey dismissal of the concern.

      1. 4

        Insofar as this change does not affect existing code behaviourally, it should be trivial for a decent compiler to canonicalise and generate the same code as it always did. Insofar as it does affect behaviour, performance is irrelevant. I have no insight into the go compiler, but if it is unable to see through this, then fixing that sounds like a much higher priority.

      2. 5

        There’s a pretty good general analysis of this as a PL design/implementation question, with discussion of what Javascript/Ruby/Python/C#/etc. each do, in a sidebar of the book Crafting Interpreters in the chapter on closures, “Design Note: Closing Over the Loop Variable”.

        1. 2

          Amazing summary. Not surprising considering that Russ Cox mentioned Dart as a source of inspiration for those new semantics, and that Robert Nystrom, the book’s author, is working on Dart :)

        2. 5

          Very interesting. As someone who only occasionally writes Go code, I had no idea about this issue.