News for hackers. Stuff that matters.
Re:Go 1.21 by panzi on Wednesday June 21, 2023 @05:00PM (#36424405)
Wait is this now heap allocating a value in every iteration of every loop? I hope that allocation is optimized out in every case where there isn't a closure over the loop variable?
Re:Go 1.21 by doctor_eval on Wednesday June 21, 2023 @05:41PM (#36425035)
Regardless of how the compiler is optimising this, I 100% agree that the old behaviour is unexpected and it’s caught me at least once. Really happy to see this (until recently) unexpected change.
Re:Go 1.21 by panzi on Wednesday June 21, 2023 @06:49PM (#36425778)
I don't actually use Go, but I have used many other languages where it is like the old behavior. I learned once that I have to build the closure correctly to get the value I want and know now to do it. Don't have any statistics on whether I made that mistake again, but anecdotally I can't remember a case where I have. In their analysis they have found a lot of cases with that mistake, though. So I guess fair enough.

However, I wonder what it will mean if someone who mostly writes Go will now use another language? Will they be more prone to make that mistake?

Re:Go 1.21 by doctor_eval on Wednesday June 21, 2023 @11:14PM (#36427607)
It's hardly standard behaviour. I mean in Java for example there didn't used to be value types, so everything was a pointer and the effect of this would be the same as the new behaviour in Go.

The only lesson to be learned here is that languages are different. But I think the new Go behaviour is more ergonomic.

Re:Go 1.21 by panzi on Thursday June 22, 2023 @09:00PM (#36441383)
In Java you can only close over final variables, so you can't close over the loop variable at all. (Unless that changed since last time I used Java, which - granted - was a long time ago.)
Re:Go 1.21 by doctor_eval on Thursday June 22, 2023 @10:50PM (#36442238)
The problem being fixed doesn’t affect only closures, but the body of the for loop itself. So for example taking the address of the loop variable would unexpectedly return the same value for the duration of the loop.
Re:Go 1.21 by quacker on Wednesday June 21, 2023 @05:10PM (#36424577)
They discuss this here: https://github.com/golang/go/wiki/LoopvarExperiment#will-the...

In fact, you can enable warnings/logs that indicate whether code that is affected by the loopvar experiment results in a stack-allocated or heap-allocated loop variable: https://github.com/golang/go/wiki/LoopvarExperiment#can-i-se...

I imagine that the current workarounds for this issue also end up with heap-allocated variables in many cases.

Re:Go 1.21 by vbezhenar on Wednesday June 21, 2023 @05:10PM (#36424576)
Of course it'll be optimized. It's just semantics that's changed. Compiler will make sure to copy variable value to new address.
Re:Go 1.21 by collinvandyck76 on Wednesday June 21, 2023 @05:09PM (#36424567)
I didn't see this optimization when I read the overview. I also hope that the compiler is smart enough to avoid this.
Re:Go 1.21 by dr2chase on Thursday June 22, 2023 @10:07AM (#36432400)
The way to view it is "unless there is syntactic sharing, it is a for loop, same as before". The compiler uses a syntactic test (with little knowledge of control flow or value use) to exclude loops from the change. This excludes most loops.

After the change, escape analysis figures out if the changed iteration variable actually needs heap allocation; in an internal sample of code that was actually buggy (i.e., biased, guaranteed to have at least one loop like this) for 5/6 of the loops escape analysis decided that heap allocation wasn't needed.

The reason this optimization isn't part of the language change proposal is that escape analysis is "behind the curtain"; ignoring performance, a program should behave the same with or without it, and it is removing heap allocations all over the place already. Escape analysis is also extremely difficult to explain exactly, so you would not want it in the spec, and "make escape analysis better" (that is, change it) is one of the prominent items in the bag of things to do for Go.

Re:Go 1.21 by xh-dude on Wednesday June 21, 2023 @05:52PM (#36425169)
Generally it is optimized out.

The fine details resemble the analysis of correctness - all the evidence shows people expect per-iteration semantics with considerable frequency, and don’t rely on per-loop semantics with measurable frequency. But it’s impossible to completely automate that assessment. Likewise, it’s impossible to automatically detect code that will spuriously allocate because of the semantic transition.