Short Variable Redeclaration

527 views
Skip to first unread message

John Souvestre

unread,
Aug 18, 2014, 9:17:14 AM8/18/14
to golan...@googlegroups.com

Hi.

 

I realize that this is by design, as per the language specification.

 

    a := 1

    a, b := 3, 3 // "a" is redeclared and "b" is declared.

 

I find this somewhat troubling.  I see that it saves a line of code (declaring b), but it also creates a chance of an unintentional redeclaration going unnoticed.  It also might result in the resulting type (after the redeclaration) not being what you expected if the first line is changed to:  a := 0.1

 

I was wondering what the logic was behind this decision?  Am I missing something?

 

Thanks,

 

John

    John Souvestre - New Orleans LA

 

Dan Kortschak

unread,
Aug 18, 2014, 9:25:17 AM8/18/14
to John Souvestre, golan...@googlegroups.com
a is not redeclared, it is assigned a new value.

http://play.golang.org/p/qDcxthnBTM

John Souvestre

unread,
Aug 18, 2014, 9:30:21 AM8/18/14
to Dan Kortschak, golan...@googlegroups.com
Hi Dan.

The language spec says:

"Unlike regular variable declarations, a short variable declaration may redeclare variables provided they were originally declared earlier in the same block 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. Redeclaration does not introduce a new variable; it just assigns a new value to the original."

So it would seem that "redeclare" means just assigning a new value, yes. But then the question becomes why use a declaration syntax for assignment?

John

John Souvestre - New Orleans LA

--
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...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Harmen B

unread,
Aug 18, 2014, 9:33:20 AM8/18/14
to John Souvestre, Dan Kortschak, golang-nuts
I suspect the use-case is mostly for the 'err' variable, so this works:

m, err := loadedMissile()
if err != nil {
   // load a missile
}

eta, err := launchMissile(m)
if err != nil {
   // ... &c.
}

John Souvestre

unread,
Aug 18, 2014, 9:40:03 AM8/18/14
to Harmen B, Dan Kortschak, golang-nuts

Hi Harmen.

 

I agree, it is handy.  But if “err” is the predominant reason for it, couldn’t you solve it by declaring “err” once, first?

 

John

    John Souvestre - New Orleans LA

 

Harmen B

unread,
Aug 18, 2014, 9:43:30 AM8/18/14
to John Souvestre, golang-nuts
Then it would look like:

var m Missile
var err Error
m, err = loadedMissile()
if err != nil {
   // ... &c.
}

var eta time.Time
eta, err = launchMissile(m)
if err != nil {
   // ... &c.
}

Which gets a bit verbose.

Dan Kortschak

unread,
Aug 18, 2014, 9:50:33 AM8/18/14
to John Souvestre, golan...@googlegroups.com
On Mon, 2014-08-18 at 08:29 -0500, John Souvestre wrote:
> So it would seem that "redeclare" means just assigning a new value,
> yes. But then the question becomes why use a declaration syntax for
> assignment?

No, redeclaration only happens when in an enclosed scope. In the example
you gave, it was a reassignment. Here is a redeclaration:

http://play.golang.org/p/ftEa-2_qPw

John Souvestre

unread,
Aug 18, 2014, 9:51:11 AM8/18/14
to Harmen B, golang-nuts

Hi Harmen.

 

The first time you could use the “:=”, since you are declaring both.  This avoids adding the extra 2 lines.  So overall you would only need the 1 extra line in the seconds call.

 

I guess my concern is with a declaration statement which sometimes doesn’t declare.

John Souvestre

unread,
Aug 18, 2014, 9:58:29 AM8/18/14
to Dan Kortschak, golan...@googlegroups.com
Hi Dan.

I think that you are using the term "redeclaration" differently than it is used in the language spec. It is a confusing term, but this statement sums it up nicely:

"Redeclaration does not introduce a new variable; it just assigns a new value to the original."

So, redeclaration doesn't declare at all. I find it easier to think about it as "nodeclaration, just assignment". Which still begs the question: Why should a declaration statement sometimes not declare?

John

John Souvestre - New Orleans LA


-----Original Message-----
From: Dan Kortschak [mailto:dan.ko...@adelaide.edu.au]
Sent: 2014 August 18, Mon 08:50
To: John Souvestre
Cc: golan...@googlegroups.com

Jan Mercl

unread,
Aug 18, 2014, 10:07:26 AM8/18/14
to John Souvestre, Dan Kortschak, golang-nuts
On Mon, Aug 18, 2014 at 3:58 PM, John Souvestre <jo...@sstar.com> wrote:
> So, redeclaration doesn't declare at all. I find it easier to think about it as "nodeclaration, just assignment". Which still begs the question: Why should a declaration statement sometimes not declare?

A (short variable) declaration statement always declares a(t least
one) new variable. The possibility to include other variable(s),
already defined in the current scope is only a convenience. IIRC, it
was not possible in the initial Go release.

It's handy for example in code like

a, err := foo()
if err != nil {
return err
}

b, err := bar()
if err != nil {
return err
}

if err = baz(a, b); err != nil {
return err
}

-j

John Souvestre

unread,
Aug 18, 2014, 10:38:53 AM8/18/14
to Jan Mercl, Dan Kortschak, golang-nuts
Hi Jan.

Is the logic that the sometimes convenience outweighs the risk? In the example you gave, what it a was previously declared and was being used for something totally different than the redeclaration? The error would be missed by the compiler, wouldn't it?

John

John Souvestre - New Orleans LA


-----Original Message-----
From: Jan Mercl [mailto:0xj...@gmail.com]
Sent: 2014 August 18, Mon 09:06
To: John Souvestre
Cc: Dan Kortschak; golang-nuts
Subject: Re: [go-nuts] Short Variable Redeclaration

Benjamin Measures

unread,
Aug 18, 2014, 10:57:53 AM8/18/14
to golan...@googlegroups.com, 0xj...@gmail.com, dan.ko...@adelaide.edu.au
On Monday, 18 August 2014 15:38:53 UTC+1, johns wrote:
Is the logic that the sometimes convenience outweighs the risk?

Just think of it as multi-assignment except that at there must be at least one declaration.

So then, what this perceived risk? How is it different from the usual confusion surrounding absent types?
a := 0.1
b := 10
// some stuff
a, b = 1, 2
// oh noes! a is not an int!

harry...@gmail.com

unread,
Aug 18, 2014, 11:19:37 AM8/18/14
to golan...@googlegroups.com, 0xj...@gmail.com, dan.ko...@adelaide.edu.au

Risk outweighs the convenience imho. What you should consider is while this (OP's original example) is perfectly fine code now, it will create a bug if the bottom portion of the code gets moved inside a for {} loop or an if {} condition. This may be 1 year later when he needs a behavior change in the application. Now the 'ignored redeclaration' silently becomes a new declaration and will have the unintended consequence of losing the "modified" value at the end of the block. Now if OP is lucky (depending on how the rest of his code is), he will get a "variable declared but not used" error. If he is unlucky, he will be banging his head against the wall for a few hours.


I am using an emacs setup recommended by Dominikh - gocode+go-lint that seems to warn me if I do this issue with an 'error' variable that i am returning - a redeclaration masking a return value. But I don't know if it will handle all situations.

Thanks
--
Harry

Gary Scarr

unread,
Aug 18, 2014, 12:25:10 PM8/18/14
to golan...@googlegroups.com

"why use a declaration syntax for assignment?"

Because it allows for type inference as part of the declaration.  Yes, this isn't helping much with very simple types and can give you some surprises with 1 vs 0.1 when you begin to use it but the type system is catching it.  If you want to explicitly declare your type separately you can, and avoid the "risk" but you quickly learn to treat := as a declaration and not an assignment.  It does require that extra bit of effort to ensure you don't move the declaration if you really only want to move the assignment.

Of course it's probably harder if you come from a Pascal or similar background where := is truly assignment.

James Wendel

unread,
Aug 18, 2014, 12:55:33 PM8/18/14
to golan...@googlegroups.com
I mainly just follow this mailing list and toy with Go a little, but this issue comes up fairly regularly. From what I remember of previous discussions, if you code Go regularly, this is a behavior you learn and understand early and it isn't an issue if you end up coding a lot of Go.

This is also something I believe the Golang caretakers wish they would have done differently, but it's done at this point and you just need to learn its behavior.

Benjamin Measures

unread,
Aug 18, 2014, 1:05:13 PM8/18/14
to golan...@googlegroups.com, 0xj...@gmail.com, dan.ko...@adelaide.edu.au
On Monday, 18 August 2014 16:19:37 UTC+1, harry...@gmail.com wrote:
Now the 'ignored redeclaration' silently becomes a new declaration and will have the unintended consequence of losing the "modified" value at the end of the block.

Not so, the spec specifically addresses this:

John Souvestre

unread,
Aug 18, 2014, 1:26:41 PM8/18/14
to Benjamin Measures, golan...@googlegroups.com, 0xj...@gmail.com, dan.ko...@adelaide.edu.au

Hi Benjamin.

 

The non-deterministic behavior of the statement, which depends on prior code located elsewhere.  It also varies, depending on what scope the other code is in.  The resulting error shows up later, not necessarily where the statement is located.  In short, it complicates testing, troubleshooting, refactoring, and maintenance.

 

And the problem could be intermittent, data dependent.  For example, imagine that the loop control variable you are using is actually a float type instead of an integer type as a result of this issued?

 

John

    John Souvestre - New Orleans LA

 

From: golan...@googlegroups.com [mailto:golan...@googlegroups.com] On Behalf Of Benjamin Measures
Sent: 2014 August 18, Mon 09:58
To: golan...@googlegroups.com
Cc: 0xj...@gmail.com; dan.ko...@adelaide.edu.au
Subject: Re: [go-nuts] Short Variable Redeclaration

 

On Monday, 18 August 2014 15:38:53 UTC+1, johns wrote:

--

John Souvestre

unread,
Aug 18, 2014, 1:32:42 PM8/18/14
to Gary Scarr, golan...@googlegroups.com

Hello Gary.

 

The Short Variable Redeclaration, when used as I presented it, isn’t type inferring for “a”.  It’s using a previously declared “a” and the type assigned then.

 

To improve the wording of the question:  Why use a declaration syntax for just assignment and not declaration?

 

John

    John Souvestre - New Orleans LA

 

--

John Souvestre

unread,
Aug 18, 2014, 1:35:29 PM8/18/14
to James Wendel, golan...@googlegroups.com
Hello James.

I did find it discussed in Issue 377. I was unable to find any consensus about changing it in Go 2.x, however.

John

John Souvestre - New Orleans LA


-----Original Message-----
From: golan...@googlegroups.com [mailto:golan...@googlegroups.com] On Behalf Of James Wendel
Sent: 2014 August 18, Mon 11:56
To: golan...@googlegroups.com
Subject: [go-nuts] Re: Short Variable Redeclaration

John Souvestre

unread,
Aug 18, 2014, 1:48:05 PM8/18/14
to Benjamin Measures, golan...@googlegroups.com, 0xj...@gmail.com, dan.ko...@adelaide.edu.au

Hi Benjamin.

 

I’m inclined to think that calling this behavior “redeclaration” is misleading and/or confusing.  The previously-declared variable is used, as it was declared then.

 

I think that perhaps “skipped-declaration” is a better description of what takes place.

 

      a := 1

      a, b := a+1, 3

      println(a, b)    // prints “2 3”

 

I believe that this shows that the previous value for “a” is used in its “re/skipped-declaration”.

 

John

    John Souvestre - New Orleans LA

 

From: golan...@googlegroups.com [mailto:golan...@googlegroups.com] On Behalf Of Benjamin Measures

Subject: Re: [go-nuts] Short Variable Redeclaration

 

On Monday, 18 August 2014 16:19:37 UTC+1, harry...@gmail.com wrote:

--

harry...@gmail.com

unread,
Aug 18, 2014, 1:50:36 PM8/18/14
to golan...@googlegroups.com, 0xj...@gmail.com, dan.ko...@adelaide.edu.au


On Monday, August 18, 2014 10:05:13 AM UTC-7, Benjamin Measures wrote:
Not so, the spec specifically addresses this:
Unlike regular variable declarations, a short variable declaration may redeclare variables provided they were originally declared earlier in the same block

I am talking about a code that changes from http://play.golang.org/p/9jAokMtnbV to this http://play.golang.org/p/6TPynNZYv9 . I understand why it prints i=0 in the second case. You might say my example is theoretical. This has occurred in reality in a bit more involved code. 

Thanks
--
Harry

Gary Scarr

unread,
Aug 18, 2014, 2:47:38 PM8/18/14
to golan...@googlegroups.com, sca...@gmail.com
:= isn't "just assignment" it's declaration and assignment inferring the type of the declaration from the assignment.  = is "just assignment".

Yes it's type-inferring for b in your case but it type-inferred a previously and is going to error if your new assignment doesn't match that type.
It's not a re-declaration if it's a different type.  My point is that you may well be getting your assignment from a function where the type declaration is a lot longer so the type inference of a short declaration is advantageous rather than declaring it on a separate line.

wkharold

unread,
Aug 18, 2014, 4:45:33 PM8/18/14
to golan...@googlegroups.com, jmwe...@gmail.com

I did find it discussed in Issue 377.  I was unable to find any consensus about changing it in Go 2.x, however.


I will bet an all expense paid trip to next year's Gopher Conference that it's not getting changed in Go 2.x. Even if consensus were reached that it presents a true "risk", which I for one don't buy, changing it would break far too much code. 

Jason Woods

unread,
Aug 18, 2014, 4:50:39 PM8/18/14
to golang-nuts
(Resending to list)
The same problem could arise with regular declaration. I can understand the concern though, but it seems to me to be part of the language and offers some interesting benefits. If you have several for loops you can use "i" for each one instead of i,j,k which when you nest one if them gets crazy.

I think block scope and shadowing is great.

Jason

Dan Kortschak

unread,
Aug 18, 2014, 5:41:25 PM8/18/14
to John Souvestre, golan...@googlegroups.com
I think that sate,ent in the spec is misleading. It does creat a new variable, but it uses an old label. The previously assigned value associated with the label does not go away, therefore the new store must actually be a new store (not surprisingly). I guess it comes down to the exact semantics of the word "variable".

It is clear form my second example that a new variable was created (with the same label) since assigning to it did not alter the value of the originally declared var. A rewrite with exactly the same behaviour using only var declarations would show that it is indeed a redeclaration wiin the nested scope.

John Souvestre

unread,
Aug 18, 2014, 6:04:20 PM8/18/14
to Dan Kortschak, golan...@googlegroups.com
Hi Dan.

The redeclaration in your second example works as expected. Yes, it is a new
variable. This is not the problem, however.

The problem case I described is when the 2 declarations are in the same block,
as in your first example. The language spec refers to both cases as a
"redeclaration". But in fact it doesn't create a new variable in the first
case. It just uses the original one, as it was declared previously.

Thus it seems incorrect to me to call the first example "redeclaration".
Indeed, I believe that doing so masks the unexpected behavior. Perhaps
calling it "skipped-redeclaration" would convey that it was attempted but not
completed - thus alerting the reader to consider the consequences.

John

    John Souvestre - New Orleans LA


-----Original Message-----
From: golan...@googlegroups.com [mailto:golan...@googlegroups.com] On
Behalf Of Dan Kortschak
Sent: 2014 August 18, Mon 16:41
To: John Souvestre
Cc: golan...@googlegroups.com
Subject: Re: [go-nuts] Short Variable Redeclaration

Dan Kortschak

unread,
Aug 18, 2014, 6:11:10 PM8/18/14
to John Souvestre, golan...@googlegroups.com
On 19/08/2014, at 7:34 AM, "John Souvestre" <jo...@sstar.com> wrote:

> The redeclaration in your second example works as expected. Yes, it is a new
> variable. This is not the problem, however.
>
> The problem case I described is when the 2 declarations are in the same block,
> as in your first example. The language spec refers to both cases as a
> "redeclaration". But in fact it doesn't create a new variable in the first
> case. It just uses the original one, as it was declared previously.
>
> Thus it seems incorrect to me to call the first example "redeclaration".
> Indeed, I believe that doing so masks the unexpected behavior. Perhaps
> calling it "skipped-redeclaration" would convey that it was attempted but not
> completed - thus alerting the reader to consider the consequences.

The first example is not, as I said, a redeclaration, it is a reassignment - because it is in the same block. This was demonstrated by trying (and failing) to assign another type to a in my first example.

I agree that there are risks associated with the use of :=, but they are outweighed by the improved legibility. And the issue you seem to see about redeclaration, is just not there.

John Souvestre

unread,
Aug 18, 2014, 6:28:16 PM8/18/14
to Dan Kortschak, golan...@googlegroups.com
Hi Dan.

> The first example is not, as I said, a redeclaration, it is a reassignment
- ...

We agree. Unfortunately the language spec refers to it as a redeclaration.

> I agree that there are risks associated with the use of :=, but they are
outweighed by the improved legibility.

Here we disagree. I consider it non-deterministic (behavior based on code
located elsewhere), hence less legible.

John

    John Souvestre - New Orleans LA


-----Original Message-----
From: golan...@googlegroups.com [mailto:golan...@googlegroups.com] On
Behalf Of Dan Kortschak
Sent: 2014 August 18, Mon 17:11
To: John Souvestre
Cc: golan...@googlegroups.com
Subject: Re: [go-nuts] Short Variable Redeclaration

Dan Kortschak

unread,
Aug 18, 2014, 6:54:21 PM8/18/14
to John Souvestre, golan...@googlegroups.com
On 19/08/2014, at 7:58 AM, "John Souvestre" <jo...@sstar.com> wrote:

>
>> The first example is not, as I said, a redeclaration, it is a reassignment
> - ...
>
> We agree. Unfortunately the language spec refers to it as a redeclaration.

Perhaps you should raise an issue on that wording.


>> I agree that there are risks associated with the use of :=, but they are
> outweighed by the improved legibility.
>
> Here we disagree. I consider it non-deterministic (behavior based on code
> located elsewhere), hence less legible

It's is by no means non-deteministic, it is contextual.

Jesse McNelis

unread,
Aug 18, 2014, 7:25:50 PM8/18/14
to John Souvestre, Dan Kortschak, golang-nuts
On Tue, Aug 19, 2014 at 8:27 AM, John Souvestre <jo...@sstar.com> wrote:
> Hi Dan.
>
> > The first example is not, as I said, a redeclaration, it is a reassignment
> - ...
>
> We agree. Unfortunately the language spec refers to it as a redeclaration.
>

It is a redeclaration. It's declaration syntax, so it has to be
declaring a variable.
In the case that a variable of that name is already declared in that
block it just redeclares that variable.
In the case that no variable of that name exists within that block it
declares a new variable of that name.

Your confuses arises from consider the creation of a new variable of
the same name as a variable in an outer scope as 'redeclaration', but
that's just a declaration of a new variable.
It's not redeclared, it's a completely different variable.

Dan Kortschak

unread,
Aug 18, 2014, 7:31:50 PM8/18/14
to Jesse McNelis, John Souvestre, golang-nuts
On Tue, 2014-08-19 at 09:25 +1000, Jesse McNelis wrote:
> It is a redeclaration. It's declaration syntax, so it has to be
> declaring a variable.

That's extremely circular reasoning.

The effect is that it's a reassignment for already declared variables in
the same inner scope.

John Souvestre

unread,
Aug 18, 2014, 7:39:02 PM8/18/14
to Jesse McNelis, Dan Kortschak, golang-nuts
Hello Jesse.

> It is a redeclaration. It's declaration syntax, so it has to be declaring a variable.

You would expect so, but it's not really "redeclaring" a or b in this example.

a := 0.1
b := 1
a, b, c := 2, b + 3, 4
println(a, b, c) // prints "+2.000000e+000 3"

It's using a's original type and b's original value.

I'm talking only about variables in the same block.

John

John Souvestre - New Orleans LA


-----Original Message-----
From: jes...@gmail.com [mailto:jes...@gmail.com] On Behalf Of Jesse McNelis
Sent: 2014 August 18, Mon 18:26
To: John Souvestre
Cc: Dan Kortschak; golang-nuts
Subject: Re: [go-nuts] Short Variable Redeclaration

John Souvestre

unread,
Aug 18, 2014, 7:41:17 PM8/18/14
to Jesse McNelis, Dan Kortschak, golang-nuts
Correction: The last line of the example should be:

println(a, b, c) // prints "+2.000000e+000 4 4"

John

John Souvestre - New Orleans LA


-----Original Message-----
From: golan...@googlegroups.com [mailto:golan...@googlegroups.com] On Behalf Of John Souvestre
Sent: 2014 August 18, Mon 18:38
To: 'Jesse McNelis'
Cc: 'Dan Kortschak'; 'golang-nuts'
Subject: RE: [go-nuts] Short Variable Redeclaration

Jesse McNelis

unread,
Aug 18, 2014, 7:58:36 PM8/18/14
to John Souvestre, Dan Kortschak, golang-nuts
On Tue, Aug 19, 2014 at 9:38 AM, John Souvestre <jo...@sstar.com> wrote:
> Hello Jesse.
>
> > It is a redeclaration. It's declaration syntax, so it has to be declaring a variable.
>
> You would expect so, but it's not really "redeclaring" a or b in this example.
>
> a := 0.1
> b := 1
> a, b, c := 2, b + 3, 4
> println(a, b, c) // prints "+2.000000e+000 3"
>
> It's using a's original type and b's original value.
>
> I'm talking only about variables in the same block.

Again, your confusion is that you think 'redeclare' is the same as
'declare a new variable of the same name'.
It's not creating a new variable, it's declaring the same variable
again. Not the same name as a new variable, the same exact variable.
If the US government were to print a document called the
"redeclaration of independance" and it has the exact same content, the
effect on the US would be nothing.

John Souvestre

unread,
Aug 18, 2014, 8:08:51 PM8/18/14
to Jesse McNelis, Dan Kortschak, golang-nuts
If it's declaring the same variable, yet using the old declaration's type and value?

> If the US government were to print a document called the "redeclaration of independance" and it has the exact same content, the effect on the US would be nothing.

You could change one copy without changing the other. Also I suspect that the value of the two copies would be vastly different.

John

John Souvestre - New Orleans LA


-----Original Message-----
From: jes...@gmail.com [mailto:jes...@gmail.com] On Behalf Of Jesse McNelis
Sent: 2014 August 18, Mon 18:58
To: John Souvestre
Cc: Dan Kortschak; golang-nuts
Subject: Re: [go-nuts] Short Variable Redeclaration

Jesse McNelis

unread,
Aug 18, 2014, 8:34:25 PM8/18/14
to John Souvestre, Dan Kortschak, golang-nuts
On Tue, Aug 19, 2014 at 10:08 AM, John Souvestre <jo...@sstar.com> wrote:
> If it's declaring the same variable, yet using the old declaration's type and value?

Declaration in Go is a statement that a variable of this name is
available within this block and any blocks that this block contains.
Redeclaration is the same statement. It's saying the same thing again,
redundantly.

The reason is that := is declaration syntax, so it must be declaring
variables. Since the variable you're attempting to declare is already
declared the short declaration will declare it again.
Declaring a variable that is already declared in the same block has no
semantic difference from the perspective of your program, but it makes
the definition of the short declaration consistent whether or not a
variable was previously declared in this block.

I feel we have different definitions of the word 'redeclaration'. But
I feel it's still the correct word to use as I can't think of another
that describes the behaviour.

John Souvestre

unread,
Aug 18, 2014, 9:10:16 PM8/18/14
to Jesse McNelis, Dan Kortschak, golang-nuts
Yes, I believe that our definitions of declare (and redeclare) differ. I associate declaring a variable with initializing it, and that isn't taking place with this type of "redeclare".

John

John Souvestre - New Orleans LA


-----Original Message-----
From: jes...@gmail.com [mailto:jes...@gmail.com] On Behalf Of Jesse McNelis
Sent: 2014 August 18, Mon 19:34
To: John Souvestre
Cc: Dan Kortschak; golang-nuts
Subject: Re: [go-nuts] Short Variable Redeclaration

Gary Scarr

unread,
Aug 18, 2014, 9:25:06 PM8/18/14
to golan...@googlegroups.com, jes...@jessta.id.au, dan.ko...@adelaide.edu.au
Since we are discussing Go it would seem prudent to use Go's definition of declare:
"A variable declaration creates a variable, binds an identifier to it and gives it a type and optionally an initial value."
and
"Unlike regular variable declarations, a short variable declaration may redeclare variables provided they were originally declared earlier in the same block 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. Redeclaration does not introduce a new variable; it just assigns a new value to the original."

So, as in C, declaration doesn't necessarily include initialization and the construct we are discussing is defined as redeclaration.

Jesse McNelis

unread,
Aug 18, 2014, 9:27:04 PM8/18/14
to John Souvestre, golang-nuts, kortschak


On 19 Aug 2014 11:09, "John Souvestre" <jo...@sstar.com> wrote:
>
> Yes, I believe that our definitions of declare (and redeclare) differ.  I associate declaring a variable with initializing it, and that isn't taking place with this type of "redeclare".
>

In C a declaration doesn't initialise.
In Go the 'var' keyword will declare and initialise variables.

The short declaration will declare the variables and then assign the given values to them. Since you're assigning values to them immediately it makes no difference whether they are initialised to anything before the assignment.

John Souvestre

unread,
Aug 18, 2014, 10:18:28 PM8/18/14
to Jesse McNelis, golang-nuts, kortschak

Hi Jesse.

 

Since we are speaking about Go, I’m using the Go Programming Language Specification as reference, not C.  The spec says that a short variable declaration “is shorthand for a regular variable declaration with initializer expressions but no types”.  It goes on to say “Redeclaration does not introduce a new variable; it just assigns a new value to the original.” 

 

Ø  Since you're assigning values to them immediately it makes no difference whether they are initialised to anything before the assignment.

 

It does makes a difference.  The type of the old variable defines the type of both of the variables, and it must be compatible with the initialization expression for the new variable.

 

As proof, I repeat the example I sent previously:

 

    a := 0.1

    b := 1

    a, b, c := 2, b + 3, 4

    println(a, b, c)  // prints "+2.000000e+000 4 4"

 

As you can see, “a” ends up a float64 rather than an int, as it would if “a” weren’t declared previously.

 

From the language spec:  “A variable declaration creates a variable, binds an identifier to it and gives it a type and optionally an initial value.”  A Short Variable Redeclaration does not create a variable, bind an identifier to it, give it a type, or allow the initial value to be optional.  It does not even come close to meeting the definition of variable declaration.  Thus my objection to the spec saying that it “redeclares” a variable.

 

I think that “skipped-declaration” or perhaps “reinitialized” is much more accurate, thus less confusing.  And I think that this clarity is important given the subtle, possibly run-time, failure modes that this feature allows.

Andrew Gerrand

unread,
Aug 19, 2014, 7:24:00 AM8/19/14
to John Souvestre, Jesse McNelis, golang-nuts, kortschak
There's some confusion here because of the expected meaning of a word versus the way the spec is using the word.

The spec tries to define the meaning of words as it introduces them. For example:

"A variable declaration creates a variable, binds an identifier to it and gives it a type and optionally an initial value."

The paragraph on redeclaration effectively defines what it means to "redeclare":

"Unlike regular variable declarations, a short variable declaration may redeclare variables provided they were originally declared earlier in the same block 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. Redeclaration does not introduce a new variable; it just assigns a new value to the original." (emphasis mine)

When interpreting the spec, it is important to avoid applying meaning to words that is not there. If it is not written in the spec, it is unspecified. :-) If what the spec says is not clear enough for a language user or implementer, the spec should be improved.

IMO the language that is there for short variable declarations is sufficient to define them and explain how they are used in practice.

I think this thread went a little off the rails earlier. To return to the crux of the issue:

In the lead up to Go 1 we discussed the various variable declaration. None of the suggested changes were compelling enough to justify changing it then, and we can't change it now because of the Go 1 compatibility promise.

FWIW, in all my years of Go programming I haven't found accidental shadowing to be an issue. In my experience you pretty quickly develop a sense for how the mechanism works, and you can easily see when you get it wrong. If you observe the idiomatic style of error handling it's even harder to make a mistake. 

Andrew

Dan Kortschak

unread,
Aug 19, 2014, 7:51:11 AM8/19/14
to Andrew Gerrand, John Souvestre, Jesse McNelis, golang-nuts
Thanks Andrew,

I think this highlights an unfortunate mistake, one that physicists
recognised a while ago in naming (and why the charges color and the
names quark exist). Terms should not be used that carry significant
semantic baggage, particularly when that semantic baggage is close to,
but not the same as, the meaning intended to be carried. That is what
has happened here.


On Tue, 2014-08-19 at 21:23 +1000, Andrew Gerrand wrote:
> There's some confusion here because of the expected meaning of a word
> versus the way the spec is using the word.
>
> The spec tries to define the meaning of words as it introduces them.
> For example:
>
> "A variable declaration creates a variable, binds an identifier to it
> and gives it a type and optionally an initial value."
>
>
> The paragraph on redeclaration effectively defines what it means to
> "redeclare":
>
> "Unlike regular variable declarations, a short variable declaration
> may redeclare variables provided they were originally declared earlier
> in the same block 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. *Redeclaration does not
> introduce a new variable; it just assigns a new value to the
> original.*" (emphasis mine)

Reply all
Reply to author
Forward
0 new messages