One thing to keep in mind is that Go development was incremental and was done, from early on, by having multiple implementations. Incremental processes often lead to different results than designing a language from a blank slate. Ambiguities in the spec are often discovered only when someone notices that implementations disagree and must be resolved somehow. Sometimes that happens after Go 1 and the resolution must happen in a way that, as much as possible, retains stability guarantees. So, it's not unsurprising if we get non-obvious spec clauses such as this.
Specifically, I can well imagine that this particular case arose, because it was discovered after the fact that one implementation contained an optimization to not evaluate the argument to `len`, while the other didn't and the question of side-effects only arose when someone noticed. I don't really know the answer to your question. I can't think of anything which would break. That being said, I also don't think it's something that really needs "fixing", as it seems a pretty uncommon concern. On Fri, Mar 18, 2022 at 4:36 PM Marvin Renich <m...@renich.org> wrote: > * 'Axel Wagner' via golang-nuts <golang-nuts@googlegroups.com> [220318 > 08:04]: > > https://go.dev/ref/spec#Length_and_capacity says: > > > > > The expression len(s) is constant if s is a string constant. The > > > expressions len(s) and cap(s) are constants if the type of s is an > array or > > > pointer to an array and the expression s does not contain channel > receives > > > or (non-constant) function calls; in this case s is not evaluated. > > > Otherwise, invocations of len and cap are not constant and s is > evaluated. > > > > So, in your case, the array contains a function call, so `len(…)` is not > > constant. > > Is the intent of that paragraph in the spec to ensure that side effects > occur? Clearly the length of [3]int{...} is constant, regardless of any > channel receives or non-constant function calls. > > Why was the spec not written as: > > .... The expressions len(s) and cap(s) are constants if the type of s > is an array or pointer to an array. If the expression s does not > contain channel receives or (non-constant) function calls, then s is > not evaluated. .... > > And then in the documentation for the range clause, say something like: > > ...: if at most one iteration variable is present, the range > expression x is only evaluated if it would be evaluated by len(x). > > This would allow > > const x = len([3]int{1, 2, f()}) > > to compile with the obvious side effects, but still result in x being a > constant. > > Is there some other reason to force len([3]int{«non-constant > initializer»}) to be non-constant? > > ...Marvin > > -- > You received this message because you are subscribed to the Google Groups > "golang-nuts" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to golang-nuts+unsubscr...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/golang-nuts/YjSm83cOcG1cACFP%40basil.wdw > . > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CAEkBMfF%2BwrFLNGXM73tkZPtw1FwxiOHArCZFtVVL91t%2BCxhpHQ%40mail.gmail.com.