Go: proposal: Go 2: allow multiple variables with all assignment variants

Created on 19 Mar 2019  路  9Comments  路  Source: golang/go

Problem

Multiple variables/steps are allowed in some assignment cases, but not others.

// Allowed
a, b := 0, 1
a, b = a+1, b-1

// Disallowed
a++, b--
a += 2, b *= 2 // and -= /= etc

As a result we stutter when two counters are adjusted together:

for {
   i, err = r.Read(b)
   got, want = got+i, want-i
   ...
}

for a, z := 0, len(s)-1; a < z; a, z = a+1, z-1 { // common slice inversion
   s[a], s[z] = s[z], s[a]
}

Proposal

Revise the spec to one of:

SimpleStmt = EmptyStmt | ExpressionStmt | SendStmt | IncDecList | Assignment | ShortVarDecl
IncDecList = IncDecStmt { "," IncDecStmt }


SimpleStmt = EmptyStmt | ExpressionStmt | SendStmt | AssignList | ShortVarDecl
AssignList = AssignCase { "," AssignCase }
AssignCase = IncDecStmt | Assignment

Allowing:

for {
   i, err = r.Read(b)
   got += i, want -= i
   ...
}

for a, z := 0, len(s)-1; a < z; a++, z-- {
   s[a], s[z] = s[z], s[a]
}

Thanks to @mingwho for raising this previously.

FrozenDueToAge Go2 LanguageChange Proposal

Most helpful comment

I don't really understand your proposal summary.

a++ is not an assignment statement.

a += 2, b -= 2 is not an assignment statement, it's a pair of assignment statements.

So I'm not sure what you mean by "allow multiple variables in all assignment statements." It seems like you mean something else: in some cases it's OK to write multiple statements separated by a comma, as long as those statements are either assignment statements or increment/decrement statements.

Are you suggesting that any place that a simple statement may occur, it's OK to have a comma separated list of assignment statements or increment/decrement statements? For example, can I write

if a += 2, b -= 3; f(a, b) {}

Why are only assignment and increment/decrement statements permitted to be used in this way? Why not any simple statement (see SimpleStmt in the language spec)?

All 9 comments

how about

got, want += i, -i

a, z += 1, -1

I don't really understand your proposal summary.

a++ is not an assignment statement.

a += 2, b -= 2 is not an assignment statement, it's a pair of assignment statements.

So I'm not sure what you mean by "allow multiple variables in all assignment statements." It seems like you mean something else: in some cases it's OK to write multiple statements separated by a comma, as long as those statements are either assignment statements or increment/decrement statements.

Are you suggesting that any place that a simple statement may occur, it's OK to have a comma separated list of assignment statements or increment/decrement statements? For example, can I write

if a += 2, b -= 3; f(a, b) {}

Why are only assignment and increment/decrement statements permitted to be used in this way? Why not any simple statement (see SimpleStmt in the language spec)?

I called a++ an assignment because it's shorthand for a=a+1. But OK, I should have written "assignment and increment/decrement statements". [Now fixed.]

Are you suggesting that any place that a simple statement may occur, it's OK to have a comma separated list of assignment statements or increment/decrement statements?

Indeed.

Why not any simple statement ...?

I don't know a reason to comma-chain other kinds. I gave common-practice examples for the assignment/inc/decrement case.

PS. Why did you open with "I don't really understand" the summary, when you clearly did?

PS. Why did you open with "I don't really understand" the summary, when you clearly did?

Because I tried to work out what you might have meant and made what appears to have been a good guess. Sometimes those guesses work, sometimes they don't.

I'm looking for a principled reason to decide which kinds of statements can be comma-chained. For example, if we do this, why not permit

    for c <- a, c <- b; ctx.Err() == nil; c <- x, c <- y { ... }

Is "let all assignment cases support multiple variables and/or steps" not a sufficient principle?

If we could write a, b <- 1, 2 then comma-chained channel sends would be reasonable :-)

Is "let all assignment cases support multiple variables and/or steps" not a sufficient principle?

I don't know what that means in terms of the language spec. The language spec doesn't have any concept of "assignment cases." It has concepts like SimpleStmt.

Can we add a concept to the spec? e.g.

SimpleStmt = EmptyStmt | ExpressionStmt | SendStmt | AssignList | ShortVarDecl
AssignList = AssignCase { "," AssignCase }
AssignCase = IncDecStmt | Assignment

Alternatively to the above spec concept, here's one with only inc/dec chains, e.g. i++, j--

SimpleStmt = EmptyStmt | ExpressionStmt | SendStmt | IncDecList | Assignment | ShortVarDecl
IncDecList = IncDecStmt { "," IncDecStmt }

I've added both to the proposal text.

This does not seem to address an important enough problem in the language. It doesn't add any functionality that we don't already have. In your examples, the only one that seems clearly simpler and easier to read is changing a, z = a+1, z-1 to a++, z-- in a for statement. Since ++ and -- is already syntactic sugar, this use seems to be piling sugar on sugar. This isn't worth the additional language complexity.

Was this page helpful?
0 / 5 - 0 ratings