Are short variable declarations necessary?

868 views
Skip to first unread message

T L

unread,
Oct 18, 2016, 10:21:52 AM10/18/16
to golang-nuts

alternative question, why followings are not accepted in syntax:

    if var x = 5; x > 3 {
        _ = x
    }

    for var x = range []int{0,1,2} {
        _ = x
       
    }

    switch var x = "abc"; x {
    default:
        _ = x
    }
   
    switch var x = (interface{}(true)).(type) {
    default:
        _ = x
    }

Ian Lance Taylor

unread,
Oct 18, 2016, 10:40:02 AM10/18/16
to T L, golang-nuts
That syntax adds no functionality and, at least to me, seems uglier
and harder to read.

Ian

T L

unread,
Oct 18, 2016, 10:50:45 AM10/18/16
to golang-nuts, tapi...@gmail.com

So the reason of adding short variable declarations is just to avoid so-called ugliness?

Pietro Gagliardi

unread,
Oct 18, 2016, 11:01:18 AM10/18/16
to T L, golang-nuts
No, the reason for short variable declarations is to avoid having to stutter the type of variables everywhere. It's part of the reason why Go is strongly typed yet doesn't fully feel that way, and was one of the main design goals at first.

Why the control statements require one, however, is something I wouldn't know.
-- 
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.

T L

unread,
Oct 18, 2016, 11:09:16 AM10/18/16
to golang-nuts, tapi...@gmail.com


On Tuesday, October 18, 2016 at 11:01:18 PM UTC+8, Pietro Gagliardi (andlabs) wrote:
No, the reason for short variable declarations is to avoid having to stutter the type of variables everywhere.

 You can also avoid having to stutter the type of variables by using var declaration.
 

Axel Wagner

unread,
Oct 18, 2016, 12:40:03 PM10/18/16
to T L, golang-nuts
The reason for short variable declarations is, that it makes reuse easier in cases of multiple return values. e.g. 

var a, err = Foo()
if err != nil {
    return err
}
var b, err = a.Bar()
if err != nil {
    return err
}

doesn't work. That being said, the duplication between ways of declaring variables has long been acknowledged as an unfortunate historical accident.


To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.

Ian Lance Taylor

unread,
Oct 18, 2016, 5:43:48 PM10/18/16
to T L, golang-nuts
I'm sorry, I don't understand what you are asking. Your examples are
about the way that various control flow statements permit a short
variable declaration. Obviously short variable declarations can also
be used as statements by themselves. I don't know what you are
referring to with your question.

Ian

Nyah Check

unread,
Oct 18, 2016, 6:06:22 PM10/18/16
to Ian Lance Taylor, T L, golang-nuts
Hi TL,

I can't talk on behalf of the creators of the language; but from my personal experience; it makes code more succinct and easier to write; something more or less like "doing more with less" if you know what I mean. It's one the the features I love the most in Go. It just makes programming more interesting. Rather spending much time writing a lot of code which I think doesn't make much sense in today's programming world where the programmer's time is very expensive compared to hardware. Le's just say it reduces the number of lines immensely in code.

In all that feature is awesome! Hope it clears your doubts.

Cheers!
Nyah
--
"The heaviest penalty for declining to rule is to be ruled by someone inferior to yourself." --Plato

T L

unread,
Oct 19, 2016, 6:22:44 AM10/19/16
to golang-nuts, ia...@golang.org, tapi...@gmail.com


On Wednesday, October 19, 2016 at 6:06:22 AM UTC+8, Nyah Check wrote:
Hi TL,

I can't talk on behalf of the creators of the language; but from my personal experience; it makes code more succinct and easier to write; something more or less like "doing more with less" if you know what I mean. It's one the the features I love the most in Go. It just makes programming more interesting. Rather spending much time writing a lot of code which I think doesn't make much sense in today's programming world where the programmer's time is very expensive compared to hardware. Le's just say it reduces the number of lines immensely in code.

> it reduces the number of lines immensely in code

sorry, from my experience, short form doesn't reduces the number of lines immensely comparing to var form.
And sometimes, more code lines are needed by using short form.
 

T L

unread,
Oct 19, 2016, 6:24:44 AM10/19/16
to golang-nuts, tapi...@gmail.com

What I mean is, if we are not forced use short forms as the first expression in control flow blocks, it would be cool.
 

Nyah Check

unread,
Oct 19, 2016, 6:25:42 AM10/19/16
to T L, golang-nuts, Ian Lance Taylor
 

sorry, from my experience, short form doesn't reduces the number of lines immensely comparing to var form.
And sometimes, more code lines are needed by using short form.

Yeah, sometimes. But we are not forced to use it though; Anyone can use any feature as they see fit.

Cheers!

Nyah Check

unread,
Oct 19, 2016, 6:28:21 AM10/19/16
to T L, golang-nuts
This can still work

var int i = 0
for  i < MAX {
  //statements here
  i++
}

Cheers!

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

Nyah Check

unread,
Oct 19, 2016, 6:30:58 AM10/19/16
to T L, golang-nuts


var int i = 0
var i int = 0 

T L

unread,
Oct 19, 2016, 6:51:06 AM10/19/16
to golang-nuts, tapi...@gmail.com


On Wednesday, October 19, 2016 at 6:28:21 PM UTC+8, Nyah Check wrote:
This can still work

var int i = 0
for  i < MAX {
  //statements here
  i++
}

Cheers!

but I don't want to leak i in outer block, and adding a {} pair is overkill.

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.

Jan Mercl

unread,
Oct 19, 2016, 6:54:19 AM10/19/16
to T L, golang-nuts
On Wed, Oct 19, 2016 at 12:51 PM T L <tapi...@gmail.com> wrote:

> but I don't want to leak i in outer block, and adding a {} pair is overkill.

That's an example answering the question in the title of this thread.

--

-j

Ian Lance Taylor

unread,
Oct 19, 2016, 10:38:18 AM10/19/16
to T L, golang-nuts
Well, you aren't forced to use it.

Ian

Michael Jones

unread,
Oct 19, 2016, 2:39:21 PM10/19/16
to Ian Lance Taylor, T L, golang-nuts
As in a number of previous questions, this one was asked poorly and the answers dance all around the intention. I had decided never to enter the fray of these oddly-put assertion/half questions, but since this is lingering, may I suggest that this is his real question:

“can we have var-style declarations in the places where the shorthand syntax is allowed?”

elaborating…

for i := 0; i < 10; i++ {…}

might also allow

for var i int; i < 10; i++ {…}

and likewise in other short-variable-permitting contexts.

Personally, it seems that the simplest argument in favor would be orthogonality and the best argument in favor would be the natural creation of multiple scope local variables. This “best” is not very strong, though, since it is unclear to me how you could introduce variables of multiple types.

Not taking sides here…just feeling that the core issue was not addressed. Nor was the much better question that was not asked, “why was the decision made in Go not to allow non-short variable declarations in these contexts?”


Ian Lance Taylor

unread,
Oct 19, 2016, 3:25:18 PM10/19/16
to Michael Jones, T L, golang-nuts
Thanks for trying to clarify.

I'm not sure I buy the orthogonality argument here. I mean, why not
permit any statement in the first clause of a for statement? Why
restrict it to just variable declarations? But if we accept that it
is restricted, I think it seems reasonable to restrict only to short
variable declarations, since `for var i int` seems to me to be ugly.

You can create multiple local variables in the for scope by writing, for example
for a, b := 0, 10; a < b; a++ {
(That would work with var, too).

Ian

Michael Jones

unread,
Oct 19, 2016, 5:17:40 PM10/19/16
to Ian Lance Taylor, T L, golang-nuts
In fact, this example hints at something important. You could do as you say and create variables of *different* types which I find very general compared to the suggested var feature:

for a, b, c := 0, 0.5, big.NewFloat(0.5).SetPrec(200); a < 15; a++ {

(https://play.golang.org/p/OM7OC3R949)

Axel Wagner

unread,
Oct 19, 2016, 5:39:31 PM10/19/16
to Michael Jones, Ian Lance Taylor, T L, golang-nuts
var could do that too:
(not that I'm advocating in favor of var in more places)

--
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+unsubscribe@googlegroups.com.

Michael Jones

unread,
Oct 19, 2016, 6:22:53 PM10/19/16
to Axel Wagner, Ian Lance Taylor, T L, golang-nuts

Interesting. I have never used var this way. I am the student here. (as in everything else!)

 

From: Axel Wagner <axel.wa...@googlemail.com>
Date: Wednesday, October 19, 2016 at 2:39 PM
To: Michael Jones <michae...@gmail.com>
Cc: Ian Lance Taylor <ia...@golang.org>, T L <tapi...@gmail.com>, golang-nuts <golan...@googlegroups.com>
Subject: Re: [go-nuts] Are short variable declarations necessary?

 

var could do that too:

(not that I'm advocating in favor of var in more places)

On Wed, Oct 19, 2016 at 11:17 PM, Michael Jones <michae...@gmail.com> wrote:

In fact, this example hints at something important. You could do as you say and create variables of *different* types which I find very general compared to the suggested var feature:

for a, b, c := 0, 0.5, big.NewFloat(0.5).SetPrec(200); a < 15; a++ {

(https://play.golang.org/p/OM7OC3R949)

-----Original Message-----
From: <golan...@googlegroups.com> on behalf of Ian Lance Taylor <ia...@golang.org>
Date: Wednesday, October 19, 2016 at 12:25 PM
To: Michael Jones <michae...@gmail.com>
Cc: T L <tapi...@gmail.com>, golang-nuts <golan...@googlegroups.com>
Subject: Re: [go-nuts] Are short variable declarations necessary?

    You can create multiple local variables in the for scope by writing, for example
        for a, b := 0, 10; a < b; a++ {
    (That would work with var, too).

--
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.

T L

unread,
Oct 20, 2016, 3:19:55 AM10/20/16
to golang-nuts, michae...@gmail.com, tapi...@gmail.com

I think the short form should be used as a supplement for the normal var form,
Specifically, short form should be used in the situation new variable identifiers and old variable identifiers are hybrid,
or the situation only new variable identifiers exist.

But now, the short form in an inner block will shadow variables in outer block.
If we really want to shadow variables in outer block, then we can just use the normal var form.
Now the design makes the short form compete with the normal var form.

 

Robert Griesemer

unread,
Oct 20, 2016, 4:31:51 PM10/20/16
to T L, golang-nuts, Michael Jones
To answer the subject line question: No, short variable declarations are not technically necessary. We could have chosen not to have them. But there are good reasons for them. It was a deliberate design decision.

Let me throw in a bit of historical perspective:

Rob's invention of ":=" in one of his prior languages, and later, our shared experience with ":=" in Sawzall (https://en.wikipedia.org/wiki/Sawzall_(programming_language)) led to the desire of wanting ":=" in Go. Variable declaration and initialization is among the most common statements written in an imperative programming language (next to simple assignment), and ":=" worked beautifully and succinctly for this purpose in the past, and it fit well into the overall design of Go.

The key here is that providing an initialization expression is mandatory with ":=" (in contrast to "just" a variable declaration), and because it's mandatory, we can omit the type of the variable (assuming we're ok with the type of the initialization expression).

At the same time we wouldn't simple give up ordinary variable declarations, using the "var" keyword. For one, at the package level, a free-standing (i.e., w/o introductory keyword) "v := x" would cause parsing difficulties and be somewhat irregular compared to all other declarations.

Thus, originally, "x := y" was simply very convenient syntactic sugar for "var x = y" and both could be used interchangeably, in most places. Go has little syntactic sugar, and where it has, it's because there's a lot of "bang for the buck" - and that's certainly the case for ":=".

The fact that "var x = y" is not permitted as a "for" loop initialization statement was simply a design decision. Ian Taylor suggested that it's "ugly". Aesthetics plaid a role here; and different people find different things attractive. There's no hard technical reason why it couldn't be permitted, it just isn't.

Finally, the special rule permitting "redeclarations" with ":=" only came in later. It gave short variable declarations different powers over regular keyword-based variable declarations. While it was considered a very useful new rule, it definitively distracted from the simple syntactic sugar regularity.

It is no secret that many people (including us) think that there may be too many different yet similar ways of declaring and initializing variables in Go; and it would be nice if a future Go could streamline and simplify this. But we should also keep in mind that variable declaration and initialization, next to simple assignment, are the most common statements in program (it's one of the few things hardware can actually do directly, which is moving data from a to b), so it does not seem unreasonable to have various ways to express that, fine-tuned for each (relatively common) use case.

- gri



--
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+unsubscribe@googlegroups.com.

Art Mellor

unread,
Oct 21, 2016, 10:20:25 AM10/21/16
to golang-nuts

One other use for := that I have seen (although I'm not necessarily a fan of this use) is to allow a function in a package to return a non-exported typed object.

E.g.

--------
package foo

type hidden struct {...}

func FooProduce() *hidden {...}
func FooConsume(h *hidden){...}

----------
package main

....
x := FooProduce()
FooConsume(x)

-----------

There's no way to declare x without exporting its type. (Ignore the simplistic case that could be reduced to FooConsume(FooProduce()) - there are other reasons to store and pass around opaque types)

Jan Mercl

unread,
Oct 21, 2016, 10:23:23 AM10/21/16
to Art Mellor, golang-nuts

On Fri, Oct 21, 2016 at 4:20 PM Art Mellor <art-goo...@dontsharemyemail.com> wrote:

> x := FooProduce()

var x = FooProduce() // Does the same, where applicable. 

--

-j

T L

unread,
Oct 21, 2016, 11:26:46 AM10/21/16
to golang-nuts, tapi...@gmail.com, michae...@gmail.com


On Friday, October 21, 2016 at 4:31:51 AM UTC+8, gri wrote:
To answer the subject line question: No, short variable declarations are not technically necessary. We could have chosen not to have them. But there are good reasons for them. It was a deliberate design decision.

Let me throw in a bit of historical perspective:

Rob's invention of ":=" in one of his prior languages, and later, our shared experience with ":=" in Sawzall (https://en.wikipedia.org/wiki/Sawzall_(programming_language)) led to the desire of wanting ":=" in Go. Variable declaration and initialization is among the most common statements written in an imperative programming language (next to simple assignment), and ":=" worked beautifully and succinctly for this purpose in the past, and it fit well into the overall design of Go.

The key here is that providing an initialization expression is mandatory with ":=" (in contrast to "just" a variable declaration), and because it's mandatory, we can omit the type of the variable (assuming we're ok with the type of the initialization expression).

At the same time we wouldn't simple give up ordinary variable declarations, using the "var" keyword. For one, at the package level, a free-standing (i.e., w/o introductory keyword) "v := x" would cause parsing difficulties and be somewhat irregular compared to all other declarations.

Thus, originally, "x := y" was simply very convenient syntactic sugar for "var x = y" and both could be used interchangeably, in most places. Go has little syntactic sugar, and where it has, it's because there's a lot of "bang for the buck" - and that's certainly the case for ":=".

The fact that "var x = y" is not permitted as a "for" loop initialization statement was simply a design decision. Ian Taylor suggested that it's "ugly". Aesthetics plaid a role here; and different people find different things attractive. There's no hard technical reason why it couldn't be permitted, it just isn't.

Finally, the special rule permitting "redeclarations" with ":=" only came in later. It gave short variable declarations different powers over regular keyword-based variable declarations. While it was considered a very useful new rule, it definitively distracted from the simple syntactic sugar regularity.

It is no secret that many people (including us) think that there may be too many different yet similar ways of declaring and initializing variables in Go; and it would be nice if a future Go could streamline and simplify this. But we should also keep in mind that variable declaration and initialization, next to simple assignment, are the most common statements in program (it's one of the few things hardware can actually do directly, which is moving data from a to b), so it does not seem unreasonable to have various ways to express that, fine-tuned for each (relatively common) use case.

- gri


Thanks, gri, this is almost the answer I want.

I still have two small questions about the short form.
1. would it be good to allow all identifiers in a short form are old ones (assume there is only one code block)?
2. would it be good/better to let identifiers in a short form not shadow outer block identifiers?
I know the second one will break compatibility. It is not a feature request. It is just a plain question.



To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.

T L

unread,
Nov 9, 2016, 5:17:55 AM11/9/16
to golang-nuts, tapi...@gmail.com, michae...@gmail.com


On Friday, October 21, 2016 at 11:26:46 PM UTC+8, T L wrote:


On Friday, October 21, 2016 at 4:31:51 AM UTC+8, gri wrote:
To answer the subject line question: No, short variable declarations are not technically necessary. We could have chosen not to have them. But there are good reasons for them. It was a deliberate design decision.

Let me throw in a bit of historical perspective:

Rob's invention of ":=" in one of his prior languages, and later, our shared experience with ":=" in Sawzall (https://en.wikipedia.org/wiki/Sawzall_(programming_language)) led to the desire of wanting ":=" in Go. Variable declaration and initialization is among the most common statements written in an imperative programming language (next to simple assignment), and ":=" worked beautifully and succinctly for this purpose in the past, and it fit well into the overall design of Go.

The key here is that providing an initialization expression is mandatory with ":=" (in contrast to "just" a variable declaration), and because it's mandatory, we can omit the type of the variable (assuming we're ok with the type of the initialization expression).

At the same time we wouldn't simple give up ordinary variable declarations, using the "var" keyword. For one, at the package level, a free-standing (i.e., w/o introductory keyword) "v := x" would cause parsing difficulties and be somewhat irregular compared to all other declarations.

Thus, originally, "x := y" was simply very convenient syntactic sugar for "var x = y" and both could be used interchangeably, in most places. Go has little syntactic sugar, and where it has, it's because there's a lot of "bang for the buck" - and that's certainly the case for ":=".

The fact that "var x = y" is not permitted as a "for" loop initialization statement was simply a design decision. Ian Taylor suggested that it's "ugly". Aesthetics plaid a role here; and different people find different things attractive. There's no hard technical reason why it couldn't be permitted, it just isn't.

Finally, the special rule permitting "redeclarations" with ":=" only came in later. It gave short variable declarations different powers over regular keyword-based variable declarations. While it was considered a very useful new rule, it definitively distracted from the simple syntactic sugar regularity.

It is no secret that many people (including us) think that there may be too many different yet similar ways of declaring and initializing variables in Go; and it would be nice if a future Go could streamline and simplify this. But we should also keep in mind that variable declaration and initialization, next to simple assignment, are the most common statements in program (it's one of the few things hardware can actually do directly, which is moving data from a to b), so it does not seem unreasonable to have various ways to express that, fine-tuned for each (relatively common) use case.

- gri


Thanks, gri, this is almost the answer I want.

I still have two small questions about the short form.
1. would it be good to allow all identifiers in a short form are old ones (assume there is only one code block)?
2. would it be good/better to let identifiers in a short form not shadow outer block identifiers?
I know the second one will break compatibility. It is not a feature request. It is just a plain question.

how about adding a ::= operator to satisfy above two rules?
 

Dave Cheney

unread,
Nov 9, 2016, 5:29:13 AM11/9/16
to golang-nuts
There are already too many ways to declare and or assign a variable in Go. Adding more is not a solution.

T L

unread,
Nov 9, 2016, 7:00:24 AM11/9/16
to golang-nuts


On Wednesday, November 9, 2016 at 6:29:13 PM UTC+8, Dave Cheney wrote:
There are already too many ways to declare and or assign a variable in Go. Adding more is not a solution.

many? I see only two ones.

Jan Mercl

unread,
Nov 9, 2016, 7:13:36 AM11/9/16
to T L, golang-nuts
On Wed, Nov 9, 2016 at 1:00 PM T L <tapi...@gmail.com> wrote:

> many? I see only two ones.

v := expr
var v = expr
var v T
var v T = expr

--

-j

Dave Cheney

unread,
Nov 9, 2016, 7:17:35 AM11/9/16
to golang-nuts, tapi...@gmail.com
and function/method parameters, and named return arguments.

T L

unread,
Nov 9, 2016, 7:36:23 AM11/9/16
to golang-nuts, tapi...@gmail.com

the last 3 and function/method parameters, and named return arguments, are just the same form.
 

--

-j

Marvin Renich

unread,
Nov 9, 2016, 10:02:35 AM11/9/16
to golang-nuts
* T L <tapi...@gmail.com> [161109 05:18]:
> On Friday, October 21, 2016 at 11:26:46 PM UTC+8, T L wrote:
> > Thanks, gri, this is almost the answer I want.
> >
> > I still have two small questions about the short form.
> > 1. would it be good to allow all identifiers in a short form are old ones
> > (assume there is only one code block)?
> > 2. would it be good/better to let identifiers in a short form not shadow
> > outer block identifiers?
> > I know the second one will break compatibility. It is not a feature
> > request. It is just a plain question.
> >
>
> how about adding a ::= operator to satisfy above two rules?

The first one would definitely not be a good design. The problem with
the short variable declaration is that you cannot tell by looking just
at that one line of code which variables are being redeclared and which
continue to refer to a previously existing variable.

Implementing the second one would only be good if it were part of fixing
the real problem, that is adding a new syntax that allows a single
combined assignment/declaration which requires each variable on the left
side to be individually identified as either a new (possibly shadowing)
variable or an existing variable that is not to be shadowed.

This has been discussed before, and does not seem likely to ever happen.

I go out of my way to avoid := when I can, to the point of writing

var x int
x, err = foo()

instead of

x, err := foo()

when err has been declared earlier in that block. There is no ambiguity
in the code on top; in the bottom statement, you have to look through
the source to find (or not find, which is more of an issue) both x and
err.

In the single variable case, where there is no ambiguity,

var x = foo()

is only three more characters than

x := foo()

and is _much_ easier to distinguish as a declaration rather than
assignment, especially for those of us who have experience in many
languages, where := can mean different things in different languages.
It is simply an issue of cognitive load.

...Marvin

T L

unread,
Nov 9, 2016, 11:57:42 AM11/9/16
to golang-nuts, mr...@renich.org

yes, := can be avoided totally.
but := really has some benefits.

The contradiction is the short form is 80% good with 20% bad side effects.
 

Marvin Renich

unread,
Nov 9, 2016, 12:23:33 PM11/9/16
to golang-nuts
* T L <tapi...@gmail.com> [161109 11:57]:
> yes, := can be avoided totally.
> but := really has some benefits.
>
> The contradiction is the short form is 80% good with 20% bad side effects.

I disagree. I saves three characters and in doing so adds much more
cognitive load to distinguish declaration from assignment. It is useful
in the condition expressions in if and for statements, but in many cases
it is easy to avoid. I say it is 20% good and 80% bad.

...Marvin

di...@veryhaha.com

unread,
Nov 9, 2016, 9:30:46 PM11/9/16
to golang-nuts, mr...@renich.org

ok, 20% good, 60% general, 20% bad, :)
 

T L

unread,
Dec 4, 2016, 3:22:30 AM12/4/16
to golang-nuts


On Wednesday, November 9, 2016 at 6:29:13 PM UTC+8, Dave Cheney wrote:
There are already too many ways to declare and or assign a variable in Go. Adding more is not a solution.

how about to prefix a ~ before identifiers to avoid shadowing:

func f() {
    a, err := 1, error.New("an error")
    if err != nil {
        ~a, b, ~err := 2, 3, nil // here the a and err is the outer a and err
    }
   
    return a, err
}
Reply all
Reply to author
Forward
0 new messages