Scope of short var declaration in if statement

6,606 views
Skip to first unread message

Rui Maciel

unread,
Dec 10, 2012, 7:22:56 AM12/10/12
to golang-nuts
In Go's specification, it is stated that the expression in Go's if
statement[1] can be preceded by a simple statement, which includes a
short var declaration. The following example (adapted) is provided:

<code>
if x := f(); x < y {
return x
}
</code>


It appears that, for this case, neither the section on If statements[1]
or variable declarations[2] provide a definition for the scope of x.

Does anyone know what's the scope of variables declared this way? And
is this info defined anywhere in the language specifications?


Thanks in advance,
Rui Maciel

[1] http://golang.org/ref/spec#If_statements
[2] http://golang.org/ref/spec#Variable_declarations

Francisco Souza

unread,
Dec 10, 2012, 7:32:08 AM12/10/12
to Rui Maciel, golang-nuts
On Mon, Dec 10, 2012 at 10:22 AM, Rui Maciel <rui.m...@gmail.com> wrote:
> In Go's specification, it is stated that the expression in Go's if
> statement[1] can be preceded by a simple statement, which includes a short
> var declaration. The following example (adapted) is provided:
>
> <code>
> if x := f(); x < y {
> return x
> }
> </code>
>
>
> It appears that, for this case, neither the section on If statements[1] or
> variable declarations[2] provide a definition for the scope of x.
>
> Does anyone know what's the scope of variables declared this way? And is
> this info defined anywhere in the language specifications?

The scope is defined by the block: http://play.golang.org/p/r37CwAA8Bd

In this example, x exists in if and else blocks, but not in the outer
block (main). As you can imagine, this can lead to shadowing:
http://play.golang.org/p/yStzjaUK5O

For more details on scoping: http://golang.org/ref/spec#Declarations_and_scope

--
~f

David Symonds

unread,
Dec 10, 2012, 7:32:41 AM12/10/12
to Rui Maciel, golang-nuts
On Mon, Dec 10, 2012 at 11:22 PM, Rui Maciel <rui.m...@gmail.com> wrote:

> <code>
> if x := f(); x < y {
> return x
> }
> </code>
...
> Does anyone know what's the scope of variables declared this way? And is
> this info defined anywhere in the language specifications?

http://golang.org/ref/spec#Declarations_and_scope says "The scope of a
constant or variable identifier declared inside a function begins at
the end of the ConstSpec or VarSpec (ShortVarDecl for short variable
declarations) and ends at the end of the innermost containing block."

The intent and implemented semantics is that the x is defined from the
end of "x := f()", and ends at the "}". I can't see in the spec where
it defines what the block is, though.
http://golang.org/ref/spec#IfStmt implies that the SimpleStmt precedes
the Block in question, which does not imply containment.


Dave.

Jan Mercl

unread,
Dec 10, 2012, 7:33:14 AM12/10/12
to Rui Maciel, golang-nuts
On Mon, Dec 10, 2012 at 1:22 PM, Rui Maciel <rui.m...@gmail.com> wrote:
> In Go's specification, it is stated that the expression in Go's if
> statement[1] can be preceded by a simple statement, which includes a short
> var declaration. The following example (adapted) is provided:
>
> <code>
> if x := f(); x < y {
> return x
> }
> </code>
>
>
> It appears that, for this case, neither the section on If statements[1] or
> variable declarations[2] provide a definition for the scope of x.
>
> Does anyone know what's the scope of variables declared this way?

Their scope is the respective block of the if, switch, for statement.
It's bit more complex. Consider:

var v /*A*/

for v /*B*/ := v /*A*/; v /*B*/ != 0; v/*B*/++ {
foo(v/*B*/)
}

> And is
> this info defined anywhere in the language specifications?

It is specified in http://golang.org/ref/spec#Short_variable_declarations

> Short variable declarations may appear only inside functions. In some contexts such
> as the initializers for if, for, or switch statements, they can be used to declare local
> temporary variables (§Statements).

-j

Rui Maciel

unread,
Dec 10, 2012, 7:48:12 AM12/10/12
to David Symonds, golang-nuts
On 12/10/2012 12:32 PM, David Symonds wrote:
> On Mon, Dec 10, 2012 at 11:22 PM, Rui Maciel <rui.m...@gmail.com> wrote:
>
>> <code>
>> if x := f(); x < y {
>> return x
>> }
>> </code>
> ...
>> Does anyone know what's the scope of variables declared this way? And is
>> this info defined anywhere in the language specifications?
>
<snip/>
>
> The intent and implemented semantics is that the x is defined from the
> end of "x := f()", and ends at the "}". I can't see in the spec where
> it defines what the block is, though.
> http://golang.org/ref/spec#IfStmt implies that the SimpleStmt precedes
> the Block in question, which does not imply containment.

Yes, that's what I suspected. I expected a behavior similar to the
scope of a var declared in a for() loop in C++. Yet, it appears that
the language specifications say nothing about that, and as the behavior
is undefined then it is only possible to assume that that behavior is
implementation-dependent.

Is there any way to submit suggestions for the language specification?


Rui Maciel

Patrick Mylund Nielsen

unread,
Dec 10, 2012, 8:16:28 AM12/10/12
to Dumitru Ungureanu, golang-nuts, David Symonds
It's extremely clear how it works. When you're having doubts, you can alway employ simple tests.

By definition the specification should be so comprehensive that you don't need to employ simple tests on a specific implementation, and so people making alternate implementations don't need to guess what the intended behavior is. A big point was made during the design of Go to make it a specification language, and to avoid such ambiguity.

Is there any way to submit suggestions for the language specification?



On Mon, Dec 10, 2012 at 2:03 PM, <itmi...@gmail.com> wrote:

On Monday, December 10, 2012 2:48:12 PM UTC+2, Rui Maciel wrote:
Is there any way to submit suggestions for the language specification? 

To what end? It's extremely clear how it works. When you're having doubts, you can alway employ simple tests.

--
 
 

Peter

unread,
Dec 10, 2012, 8:36:12 AM12/10/12
to golan...@googlegroups.com, itmi...@gmail.com
In addition, you would need to know:
 
Each if, for, and switch statement is considered to be in its own implicit block.
 
 The scope of a constant or variable identifier declared inside a function begins at the end of the ConstSpec or VarSpec (ShortVarDecl for short variable declarations) and ends at the end of the innermost containing block.

 
On Monday, 10 December 2012 13:19:03 UTC, itmi...@gmail.com wrote:
On Monday, December 10, 2012 2:22:56 PM UTC+2, Rui Maciel wrote:
In Go's specification, it is stated that the expression in Go's if

Does anyone know what's the scope of variables declared this way?  And
is this info defined anywhere in the language specifications?

Obviously in the Go specs: http://golang.org/ref/spec
You have there, a link in the definition: SimpleStmt.

Click on ShortVarDecl and you'll get your answer: 

In some contexts such as the initializers for if , for , or switch statements, they can be used to declare local temporary variables

Rui Maciel

unread,
Dec 10, 2012, 8:56:01 AM12/10/12
to Francisco Souza, golang-nuts
On 12/10/2012 12:32 PM, Francisco Souza wrote:
> The scope is defined by the block:http://play.golang.org/p/r37CwAA8Bd
> In this example, x exists in if and else blocks, but not in the outer
> block (main). As you can imagine, this can lead to shadowing:
> http://play.golang.org/p/yStzjaUK5O
>
> For more details on scoping:http://golang.org/ref/spec#Declarations_and_scope

My point is, where is that behavior defined? If it isn't defined
anywhere in the specs then there is no assurance that that behavior can
be expected in any implementation.


Rui Maciel

Rui Maciel

unread,
Dec 10, 2012, 9:01:01 AM12/10/12
to golan...@googlegroups.com
On 12/10/2012 01:03 PM, itmi...@gmail.com wrote:
> To what end? It's extremely clear how it works. When you're having doubts,
> you can alway employ simple tests.

Tests are meaningless. They can only assert the outcome of a specific
test ran on a specific version of a specific implementation. They don't
define the behavior of a language, nor do they ensure that every
implementation works that way, or even if different versions of the same
implementation display a similar behavior. If it isn't in the specs
then no implementation is required to implement it. That's a problem.


Rui Maciel

Rui Maciel

unread,
Dec 10, 2012, 9:08:57 AM12/10/12
to golan...@googlegroups.com
Please don't troll this thread, too.

Rui Maciel

On 12/10/2012 01:19 PM, itmi...@gmail.com wrote:
> On Monday, December 10, 2012 2:22:56 PM UTC+2, Rui Maciel wrote:
>
>> >In Go's specification, it is stated that the expression in Go's if
>> >
>> >Does anyone know what's the scope of variables declared this way? And
>> >is this info defined anywhere in the language specifications?
>> >
> Obviously in the Go specs:http://golang.org/ref/spec
> You have there, a link in the definition: SimpleStmt<http://translate.googleusercontent.com/translate_c?anno=2&depth=1&hl=en&rurl=translate.google.com&sl=auto&tl=nl&twu=1&u=http://golang.org/ref/spec&usg=ALkJrhizMJdnnxaJ2BQy49R2GEMozpA9LQ#SimpleStmt>
> .
> This will lead you to: SimpleStmt = EmptyStmt<http://translate.googleusercontent.com/translate_c?anno=2&depth=1&hl=en&rurl=translate.google.com&sl=auto&tl=nl&twu=1&u=http://golang.org/ref/spec&usg=ALkJrhizMJdnnxaJ2BQy49R2GEMozpA9LQ#EmptyStmt>|
> ExpressionStmt<http://translate.googleusercontent.com/translate_c?anno=2&depth=1&hl=en&rurl=translate.google.com&sl=auto&tl=nl&twu=1&u=http://golang.org/ref/spec&usg=ALkJrhizMJdnnxaJ2BQy49R2GEMozpA9LQ#ExpressionStmt>|
> SendStmt<http://translate.googleusercontent.com/translate_c?anno=2&depth=1&hl=en&rurl=translate.google.com&sl=auto&tl=nl&twu=1&u=http://golang.org/ref/spec&usg=ALkJrhizMJdnnxaJ2BQy49R2GEMozpA9LQ#SendStmt>|
> IncDecStmt<http://translate.googleusercontent.com/translate_c?anno=2&depth=1&hl=en&rurl=translate.google.com&sl=auto&tl=nl&twu=1&u=http://golang.org/ref/spec&usg=ALkJrhizMJdnnxaJ2BQy49R2GEMozpA9LQ#IncDecStmt>|
> Assignment<http://translate.googleusercontent.com/translate_c?anno=2&depth=1&hl=en&rurl=translate.google.com&sl=auto&tl=nl&twu=1&u=http://golang.org/ref/spec&usg=ALkJrhizMJdnnxaJ2BQy49R2GEMozpA9LQ#Assignment>|
> ShortVarDecl<http://translate.googleusercontent.com/translate_c?anno=2&depth=1&hl=en&rurl=translate.google.com&sl=auto&tl=nl&twu=1&u=http://golang.org/ref/spec&usg=ALkJrhizMJdnnxaJ2BQy49R2GEMozpA9LQ#ShortVarDecl>
>
> Click on ShortVarDecl<http://translate.googleusercontent.com/translate_c?anno=2&depth=1&hl=en&rurl=translate.google.com&sl=auto&tl=nl&twu=1&u=http://golang.org/ref/spec&usg=ALkJrhizMJdnnxaJ2BQy49R2GEMozpA9LQ#ShortVarDecl> and

Rui Maciel

unread,
Dec 10, 2012, 9:13:07 AM12/10/12
to golan...@googlegroups.com
On 12/10/2012 01:36 PM, Peter wrote:
> In addition, you would need to know:
>
>
>> >Each if, for, and switch statement is considered to be in its own implicit
>> >block.
>> >

Peter,

Thanks for your reply.

It appears that implicit blocks do define the scope of variables
declared this way. If the if statement's implicit block is equivalent to:

<code>
{
x := f()
if x < y {
return x
}
}
</code>

...then there is no ambiguity.


Thanks for the help,
Rui Maciel

Rui Maciel

unread,
Dec 10, 2012, 9:14:05 AM12/10/12
to golan...@googlegroups.com
On 12/10/2012 01:16 PM, Patrick Mylund Nielsen wrote:
>> >Is there any way to submit suggestions for the language specification?
Thanks for the help, Patrick.


Rui Maciel

Peter

unread,
Dec 10, 2012, 9:18:51 AM12/10/12
to golan...@googlegroups.com
No problem. I think we all believe it's important that the Go spec is comprehensive and precise, and discussions like this help make sure it is.

chris dollin

unread,
Dec 10, 2012, 10:18:58 AM12/10/12
to itmi...@gmail.com, golan...@googlegroups.com
On 10 December 2012 15:07, <itmi...@gmail.com> wrote:
> And for the record, I was pointing you exactly where the answer is in the
> documentation.
>
> Again, these are the steps:
> The if statement: http://golang.org/ref/spec#If_statements
>
> IfStmt = "if" [ SimpleStmt ";" ] Expression Block [ "else" ( IfStmt | Block
> ) ]
>
>
> Click SimpleStmt.
> You end up here: http://golang.org/ref/spec#SimpleStmt
>
> SimpleStmt = EmptyStmt | ExpressionStmt | SendStmt | IncDecStmt | Assignment
> | ShortVarDecl .
>
>
> Click ShortVarDecl.
> You end up here: http://golang.org/ref/spec#ShortVarDecl
>
> Here it says:
>
>> In some contexts such as the initializers for if, for, or switch
>> statements, they can be used to declare local temporary variables
>
> There you have it, written in the specs.

Original question:

)) Does anyone know what's the scope of variables declared this way?
)) And is this info defined anywhere in the language specifications?

This question isn't answered by the text you display.

Chris

--
Chris "not called Ron" Dollin

chris dollin

unread,
Dec 10, 2012, 10:23:06 AM12/10/12
to itmi...@gmail.com, golan...@googlegroups.com
On 10 December 2012 15:18, chris dollin <ehog....@googlemail.com> wrote:

> Original question:
>
> )) Does anyone know what's the scope of variables declared this way?
> )) And is this info defined anywhere in the language specifications?
>
> This question isn't answered by the text you display.

(And to clarify: by "this question" I meant "what's the scope of variables
declared this way".)

Chris

--
Chris "Sir! I know, sir! Me!" Dollin

Patrick Mylund Nielsen

unread,
Dec 10, 2012, 10:37:22 AM12/10/12
to Dumitru Ungureanu, golang-nuts, chris dollin
QED you are having this discussion, so the spec likely isn't clear enough.


On Mon, Dec 10, 2012 at 4:25 PM, <itmi...@gmail.com> wrote:
On Monday, December 10, 2012 5:18:58 PM UTC+2, chris dollin wrote:
Original question:

)) Does anyone know what's the scope of variables declared this way?
)) And is this info defined anywhere in the language specifications?

This question isn't answered by the text you display.


"[...]local temporary variables" looks like scope resolution to me.

http://golang.org/ref/spec#ShortVarDecl look like a "somewhere" in the language specs to me.


Also, earlier, I provided with a shorter explanation:
"Those vars will be accessible in the if block and any following else blocks."


Now, is there something here you don't agree with?

--
 
 

Rui Maciel

unread,
Dec 10, 2012, 10:58:01 AM12/10/12
to golan...@googlegroups.com
On 12/10/2012 03:18 PM, chris dollin wrote:
> Original question:
>
> )) Does anyone know what's the scope of variables declared this way?
> )) And is this info defined anywhere in the language specifications?
>
> This question isn't answered by the text you display.

On top of that, those links were already included in the original post,
and they say nothing relevant about this issue. So, not only was it not
helpful but it also contributed nothing to the discussion.


Rui Maciel

George Shammas

unread,
Dec 10, 2012, 11:11:06 AM12/10/12
to golang-nuts
Your all a bunch of teenagers. Continually bickering. itmitica being
the worst offender.

But for the sake of everyone else, can you all not do 3+ replies in a
row? It creates even more noise from an already noisy group.
Completely unnecessary.

chris dollin

unread,
Dec 10, 2012, 11:53:43 AM12/10/12
to itmi...@gmail.com, golan...@googlegroups.com
On 10 December 2012 15:25, <itmi...@gmail.com> wrote:
>> On Monday, December 10, 2012 5:18:58 PM UTC+2, chris dollin wrote:
>> Original question:
>>
>> )) Does anyone know what's the scope of variables declared this way?
>> )) And is this info defined anywhere in the language specifications?
>>
>> This question isn't answered by the text you display.

> "[...]local temporary variables" looks like scope resolution to me.

Scopes have beginnings and endings. An answer would supply both.
"Local temporay variables" doesn't say what the locality is, although
I agree that the beginning is pretty much a given. The end, however ...

> http://golang.org/ref/spec#ShortVarDecl look like a "somewhere" in the
> language specs to me.

Oh, yes, but it doesn't answer the question (and that wasn't the bit
I was taking issue with, as my follow-up clarification -- which you
may not have seen -- makes explicit).

> Also, earlier, I provided with a shorter explanation:
> "Those vars will be accessible in the if block and any following else
> blocks."

That wasn't in the text you have just presented as "there you
have it, written in the specs". What you quoted wasn't sufficient
(and is also badly worded because of the ambiguation of "following
else clauses").

> Now, is there something here you don't agree with?

Yes.

Chris

[viz, that whay you said in your message was The Answer.]


--
Chris "allusive" Dollin

Kyle Lemons

unread,
Dec 12, 2012, 1:18:28 PM12/12/12
to itmi...@gmail.com, golang-nuts
On Wed, Dec 12, 2012 at 1:16 PM, <itmi...@gmail.com> wrote:
For any other takers, the tour specifies and clarifies this:

http://tour.golang.org/#22

Like for, the if statement can start with a short statement to execute before the condition.

Variables declared by the statement are only in scope until the end of the if.


I will point out that the quoted text does not address whether it is in scope for the else clauses.
 

--
 
 

Rui Maciel

unread,
Dec 12, 2012, 1:30:33 PM12/12/12
to golan...@googlegroups.com
On 12/12/2012 06:18 PM, Kyle Lemons wrote:
> I will point out that the quoted text does not address whether it is in
> scope for the else clauses.

Moreover, it's not the language specification, and therefore it is
irrelevant for this discussion.

The answer for this question was already given by Peter, by referring to
the definition of implicit blocks in the specs.

http://golang.org/ref/spec#Blocks


Rui Maciel

Rui Maciel

unread,
Dec 12, 2012, 1:31:33 PM12/12/12
to golan...@googlegroups.com
On 12/12/2012 06:25 PM, itmi...@gmail.com wrote:
> To this regard, the tour is quite useful.

It is also quite irrelevant, because no matter how useful and handy it
might be, the language is not defined by the tour.


Rui Maciel

alexjl...@gmail.com

unread,
Dec 24, 2013, 10:24:55 PM12/24/13
to golan...@googlegroups.com, rui.m...@gmail.com
It took me forever to figure this out... thanks!

I agree that although the language spec is very detailed and clear, it is a bit difficult to find the specific section that specifies the scope of short variable declarations in the first line of if/for statements. I initially assumed that this information would be mentioned in a section about "scopes" or maybe even "short variable declarations"... however, it didn't occur to me to look at the section titled "Blocks" until I saw this thread.

I have no opinion on whether or not the language spec is updated to make this more clear... I trust the language designers to make the decision they feel is best. I just felt the need to voice my opinion on the matter since it took me a longer-than-expected amount of time to figure it out. :)
Reply all
Reply to author
Forward
0 new messages