Re: [go-nuts] Language spec question: why is k, v := k, v allowed in a for loop with range?

2020-01-12 Thread Silvan Jegen
Jan Mercl <0xj...@gmail.com> wrote:
> On Sun, Jan 12, 2020 at 10:10 AM Silvan Jegen  wrote:
> 
> > So the declaration of the variables in the for loop itself is in outer
> > scope compared to the body of the for loop?
> 
> The outer scope begins immediately after the keyword "for". The inner
> one is an ordinary block scope and it begins immediately after the
> '{'.

Ah, I see.


> > In that case, redeclaring them
> > in the inner scope (== the loop body) would not be allowed either, no?
> 
> This is valid: { a := 42; f(a) { a := 24; f(a) }}

Right, that makes sense!

So my confusion stemmed from me not realizing that the variable
declaration in the range clause forms its own scope while the for body
constitutes another one. I assumed they belonged in the same scope.

So the spec seems fine. Thanks to you and Dan for clearing that up for me!
 

Cheers,

Silvan

-- 
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/2YH00XKBNL6QF.26M7JWLHO8QO4%40homearch.localdomain.


Re: [go-nuts] Language spec question: why is k, v := k, v allowed in a for loop with range?

2020-01-12 Thread Jan Mercl
On Sun, Jan 12, 2020 at 10:10 AM Silvan Jegen  wrote:

> So the declaration of the variables in the for loop itself is in outer
> scope compared to the body of the for loop?

The outer scope begins immediately after the keyword "for". The inner
one is an ordinary block scope and it begins immediately after the
'{'.

> In that case, redeclaring them
> in the inner scope (== the loop body) would not be allowed either, no?

This is valid: { a := 42; f(a) { a := 24; f(a) }}

-- 
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/CAA40n-VfV6GSBs9EapNnezdC_GZ15ENYrE9VTWFBNkn6DZgJVA%40mail.gmail.com.


Re: [go-nuts] Language spec question: why is k, v := k, v allowed in a for loop with range?

2020-01-12 Thread Dan Kortschak
On Sun, 2020-01-12 at 10:10 +0100, Silvan Jegen wrote:
> So the declaration of the variables in the for loop itself is in
> outer scope compared to the body of the for loop?

Yes.

> In that case, redeclaring them in the inner scope (== the loop body)
> would not be allowed either, no?

What?

The body is a new scope, so the redeclaration is valid without any new
vars.

This can be demonstrated here: https://play.golang.org/p/Xpc40xZVzz8

-- 
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/78c88f6c6a32e328f79a54b16fd1238c108f7e16.camel%40kortschak.io.


Re: [go-nuts] Language spec question: why is k, v := k, v allowed in a for loop with range?

2020-01-12 Thread Silvan Jegen
Dan Kortschak  wrote:
> The gopher operator is allowed to be used because the body of the for
> loop is a new scope. In the second example, the a, b := b, a is not in
> a new scope.

So the declaration of the variables in the for loop itself is in outer
scope compared to the body of the for loop? In that case, redeclaring them
in the inner scope (== the loop body) would not be allowed either, no?

It also wouldn't explain the k := k case since ':=' has to redeclare at
least one new variable according to the spec.


Cheers,

Silvan


> On Sun, 2020-01-12 at 09:09 +0100, Silvan Jegen wrote:
> > Hi fellow gophers
> > 
> > The following code compiles
> > 
> > 
> > package main
> > 
> > import (
> > "fmt"
> > )
> > 
> > func main() {
> > mymap := map[string]int{"a": 1, "b": 2}
> > for k, v := range mymap {
> > k, v := k, v
> > fmt.Printf("k %s, v: %d\n", k, v)
> > }
> > }
> > 
> > 
> > while this one doesn't.
> > 
> > 
> > package main
> > 
> > import (
> > "fmt"
> > )
> > 
> > func main() {
> > a := 1
> > b := 2
> > a, b := a, b
> > fmt.Printf("a %d, b: %d\n", a, b)
> > }
> > 
> > 
> > I looked at the language spec and for the ':=' (the "walrus
> > operator") in
> > the "Short variable declarations"[0] section the spec says the
> > following.
> > 
> > "Unlike regular variable declarations, a short variable declaration
> > may redeclare variables provided they were originally declared
> > earlier
> > in the same block (or the parameter lists if the block is the
> > function
> > body) with the same type, and at least one of the non-blank variables
> > is
> > new. As a consequence, redeclaration can only appear in a multi-
> > variable
> > short declaration."
> > 
> > This explains why the second example doesn't compile since none of
> > the
> > variables in the second short variable declaration is new.
> > 
> > The same is true for the first example however and this one compiles
> > just fine (even when using a short variable declaration on only one
> > variable like in 'k := k' which shouldn't be allowed either according
> > to this quote).
> > 
> > The only explanation for this that I could come up with after being
> > asked
> > about this case is that the variables declared in the range clause
> > are
> > a special case, the so called "iteration variables" according to the
> > "For statements" section[1]. The spec does not mention this but for
> > these "iteration variables" the rules for the regular short variable
> > declaration don't seem to uply. If that is indeed the case, I wonder
> > if
> > the spec shouldn't be updated to reflect this.
> > 
> > Is this really the case or am I missing something?
> > 
> > 
> > Cheers,
> > 
> > Silvan
> > 
> > 
> > [0] https://golang.org/ref/spec#Short_variable_declarations
> > [1] https://golang.org/ref/spec#For_statements
> > 


-- 
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/3ACN5GJSNWCY4.39YVVWTJK8DYN%40homearch.localdomain.


Re: [go-nuts] Language spec question: why is k, v := k, v allowed in a for loop with range?

2020-01-12 Thread Dan Kortschak
The gopher operator is allowed to be used because the body of the for
loop is a new scope. In the second example, the a, b := b, a is not in
a new scope.

On Sun, 2020-01-12 at 09:09 +0100, Silvan Jegen wrote:
> Hi fellow gophers
> 
> The following code compiles
> 
> 
> package main
> 
> import (
>   "fmt"
> )
> 
> func main() {
>   mymap := map[string]int{"a": 1, "b": 2}
>   for k, v := range mymap {
>   k, v := k, v
>   fmt.Printf("k %s, v: %d\n", k, v)
>   }
> }
> 
> 
> while this one doesn't.
> 
> 
> package main
> 
> import (
>   "fmt"
> )
> 
> func main() {
>   a := 1
>   b := 2
>   a, b := a, b
>   fmt.Printf("a %d, b: %d\n", a, b)
> }
> 
> 
> I looked at the language spec and for the ':=' (the "walrus
> operator") in
> the "Short variable declarations"[0] section the spec says the
> following.
> 
> "Unlike regular variable declarations, a short variable declaration
> may redeclare variables provided they were originally declared
> earlier
> in the same block (or the parameter lists if the block is the
> function
> body) with the same type, and at least one of the non-blank variables
> is
> new. As a consequence, redeclaration can only appear in a multi-
> variable
> short declaration."
> 
> This explains why the second example doesn't compile since none of
> the
> variables in the second short variable declaration is new.
> 
> The same is true for the first example however and this one compiles
> just fine (even when using a short variable declaration on only one
> variable like in 'k := k' which shouldn't be allowed either according
> to this quote).
> 
> The only explanation for this that I could come up with after being
> asked
> about this case is that the variables declared in the range clause
> are
> a special case, the so called "iteration variables" according to the
> "For statements" section[1]. The spec does not mention this but for
> these "iteration variables" the rules for the regular short variable
> declaration don't seem to uply. If that is indeed the case, I wonder
> if
> the spec shouldn't be updated to reflect this.
> 
> Is this really the case or am I missing something?
> 
> 
> Cheers,
> 
> Silvan
> 
> 
> [0] https://golang.org/ref/spec#Short_variable_declarations
> [1] https://golang.org/ref/spec#For_statements
> 

-- 
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/3eee83daa8acb80043d73d7df454a8d5608cb720.camel%40kortschak.io.


Re: [go-nuts] Language spec question: why is k, v := k, v allowed in a for loop with range?

2020-01-12 Thread Ian Davis
The range clause introduces a new scope. See this version of your second 
example: https://play.golang.org/p/UXI_w6B4DW5

-- Ian

On Sun, 12 Jan 2020, at 8:09 AM, Silvan Jegen wrote:
> Hi fellow gophers
> 
> The following code compiles
> 
> 
> package main
> 
> import (
>   "fmt"
> )
> 
> func main() {
>   mymap := map[string]int{"a": 1, "b": 2}
>   for k, v := range mymap {
>   k, v := k, v
>   fmt.Printf("k %s, v: %d\n", k, v)
>   }
> }
> 
> 
> while this one doesn't.
> 
> 
> package main
> 
> import (
>   "fmt"
> )
> 
> func main() {
>   a := 1
>   b := 2
>   a, b := a, b
>   fmt.Printf("a %d, b: %d\n", a, b)
> }
> 
> 
> I looked at the language spec and for the ':=' (the "walrus operator") in
> the "Short variable declarations"[0] section the spec says the following.
> 
> "Unlike regular variable declarations, a short variable declaration
> may redeclare variables provided they were originally declared earlier
> in the same block (or the parameter lists if the block is the function
> body) with the same type, and at least one of the non-blank variables is
> new. As a consequence, redeclaration can only appear in a multi-variable
> short declaration."
> 
> This explains why the second example doesn't compile since none of the
> variables in the second short variable declaration is new.
> 
> The same is true for the first example however and this one compiles
> just fine (even when using a short variable declaration on only one
> variable like in 'k := k' which shouldn't be allowed either according
> to this quote).
> 
> The only explanation for this that I could come up with after being asked
> about this case is that the variables declared in the range clause are
> a special case, the so called "iteration variables" according to the
> "For statements" section[1]. The spec does not mention this but for
> these "iteration variables" the rules for the regular short variable
> declaration don't seem to uply. If that is indeed the case, I wonder if
> the spec shouldn't be updated to reflect this.
> 
> Is this really the case or am I missing something?
> 
> 
> Cheers,
> 
> Silvan
> 
> 
> [0] https://golang.org/ref/spec#Short_variable_declarations
> [1] https://golang.org/ref/spec#For_statements
> 
> -- 
> 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/3L6DOOAAM4RP6.2NDJ7GRYRRO2B%40homearch.localdomain.
>

-- 
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/e61675a2-7e2e-449b-b443-cc6487d9cfe5%40www.fastmail.com.