Skip to content

proposal: Go 2: reform the variable redeclaration syntax to avoid some confusions and inconveniences #38388

Closed
@zigo101

Description

@zigo101

(The following content is a rewritten and an improvement version of this comment)

Abstract

This proposal tries to avoid some problems caused by short variable declarations (a.k.a., variable redeclarations), by introducing a scope viewer identifier concept and using labels as scope viewer identifiers.

Background

We all know that, although short variable declarations (x, y := a, b) do solve some problems, they also brings some new ones. The new problems include:

  1. break the one way to do a specified thing principle in Go. We all know that short declarations overlap too much with standard declarations in functionalities.
  2. short declarations brings some confusions to Go programmers, in particular to new gophers.

Proposal

Proposal part 1: scope viewers

The proposal proposes that we can re-use labels as scope viewer identifiers. The following code shows what are scope viewer identifiers:

func f() {
	var a = 1
x:
	{
	y:
		var a = 2
	z:
		{
			var a = 3
			
			// x:a <=> y:a
			println(x:a, y:a, z:a, a) // 1 1 2 3
		}
	}
}

Proposal part 2: syntax sugars

There are two sugars for the scope:identifier notation.

  1. :identifier (without the scope prefix), means the innermost declared identifier (it is equivalent to *&identifier).
  2. ::identifier, means the package-level declared identifier.

(Digression 1: is it good to view package import names as scope viewer identifiers? So that we can use aPkg::ExportIdentifier to use exported resources.)

(Digression 2: the proposal may also discard the above described scope viewer concept and only contain the following content, by replacing :identifier with *&identifier and using *&identifier as redeclared items.)

Proposal part 3: avoid using short declarations by using scope viewer identifiers

The proposal proposes that we can relax the restriction of the left items in standard variable declarations. Now all left items must be pure identifiers. We can relax the rules as selectors, dereferences, element indexing, and the above mentioned scope:identifier forms are allowed to show up as target values in the left items of a standard variable declaration, as long as there is at least one pure identifier in the left items as well. When the declaration is executed at run time, the new variables represented by pure identifiers are initialized, others are re-assigned with new values. The following is an example without using labels:

 type T struct {
        i *int
        s []int
 }
 var t T
 var p = new(int)

 func bar() {
       // "err" is new declared, others are not.
       var *p, t.i, t.s[1], :p, err = 1, p, 2, t.i, errors.New("bar")
       // *:p is not valid. In other words, :id must show up independently.
       ...
 }

Another more common use case:

    package bar

    func foo() {
       var x, err = f()
       ...
       // Here "err" means the "err" declared above.
       var y, z, :err = g()
s:
       ...
       {
           // The "err" also means the "err" declared above.
           var w, :err = h()
           ...
           // This "err" is a new declared one.
           var m, n, err = k()
           ...
           
           {
           	// This "err" means the first error declared above.
           	var p, q, s:err = l()
           	...
           }
       }
    }

The := redeclaration syntax should be kept ONLY in the simple statements in control flows, just for aesthetics reason. In other words, ... := ... is totally a shorthand of var ... = ... in the simple statements in control flows.

    if a, b := c, d; a {
    }
    //<=>
    if var a, b = c, d; a { // some ugly
    }
    // However, personally, I also think the ugly version is acceptable.

Rationale

Please see the above backgroud part.

Compatibility

The idea should be Go 1 compatible. What I mean here is the above proposed new redeclaration syntax may coexist with the current standard and short variable declarations.

It is easy to let go fix translate short variable declarations into the above proposed new syntax form. The short declarations in the simple statements in control flows don't need to be translated.

If it needs, the current short declaration uses can be removed eventually.

Implementation

Compiler parsers should consider the new syntax form.

One new statement might need to be added to go/ast standard package.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions