Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proposal: Go 2: syntax for declaring nested structs #25848

Closed
nmrshll opened this issue Jun 12, 2018 · 4 comments
Closed

proposal: Go 2: syntax for declaring nested structs #25848

nmrshll opened this issue Jun 12, 2018 · 4 comments
Labels
FrozenDueToAge LanguageChange Suggested changes to the Go language Proposal v2 An incompatible library change
Milestone

Comments

@nmrshll
Copy link

nmrshll commented Jun 12, 2018

One of the frustrating points for newcomers to Go is the syntax for declaring nested structs. Especially considering other languages make it concise and easily memorable.

Right now that syntax for declaring it in one go looks like this:

type B struct {
	Name        string `json:"name"`
	Description string `json:"description"`
	Tags        string `json:"tags"`
}
type A struct {
	B B `json:"b"`
}

// Syntax for declaring instances of A or B
b := B{
	Name: "somename",
}
a := &A{
	B: B{
		Name:        "somename",
		Description: "abc",
	},
}

And I've noticed a few times that intuitively, people tend to keep the struct A declaration nested, and try to guess the syntax for declaring one instance of it.
That syntax is the following, and it's pretty complicated (again I'm comparing to other scripting languages that provide no type safety at all, it's a pretty unfair comparison):

type A struct {
	B struct {
		Name        string `json:"name"`
		Description string `json:"description"`
		Tags        string `json:"tags"`
	} `json:"b"`
}

// Syntax for declaring an instance of A
// notice it's impossible to declare an instance of B, it not being a type by itself
a := &A{
	B: struct {
		Name        string `json:"name"`
		Description string `json:"description"`
		Tags        string `json:"tags"`
	}{
		Name:        "somename",
		Description: "abc",
	},
}

Which leads to my syntax proposal for doing the same thing:

// even while keeping the type declaration nested
type A struct {
	B struct {
		Name        string `json:"name"`
		Description string `json:"description"`
		Tags        string `json:"tags"`
	} `json:"b"`
}
// A.B would automatically be accessible as a type itself
b := A.B{
	Name: "somename",
}
// creating an A would be more concise without losing any clarity about types
a := &A{
	B: A.B{
		Name:        "somename",
		Description: "abc",
	},
}

What is your opinion about this syntax ?

I'm not familiar with the go codebase yet, but I'd be happy to start looking into it, I just wish to see how the go community would receive such a change first.

Also, are there strong reasons (that I don't see) to not introduce that change ?

@bcmills bcmills changed the title Syntax proposal for declaring nested structs in Go proposal: spec: syntax for declaring nested structs Jun 12, 2018
@gopherbot gopherbot added this to the Proposal milestone Jun 12, 2018
@bcmills bcmills added LanguageChange Suggested changes to the Go language v2 An incompatible library change and removed Proposal labels Jun 12, 2018
@bcmills
Copy link
Contributor

bcmills commented Jun 12, 2018

#21496 seems like a clearer way to address the same use-case.

@ianlancetaylor ianlancetaylor changed the title proposal: spec: syntax for declaring nested structs proposal: Go 2: syntax for declaring nested structs Jun 12, 2018
@nmrshll
Copy link
Author

nmrshll commented Jun 12, 2018

@bcmills that's a valid point, thanks for pointing to the other issue.

I'm not sure if the elision would always be clearer, but it's certainly more concise, and there's always the possibility of specifying types if any code gets unclear, so I'd be happy with the solution you pointed out !

I also like the idea of making sub-types accessible without breaking the nesting visually though.

@deanveloper
Copy link

I don't like this, mainly because now A.B becomes ambiguous. It's not intuitive to me to have A.B sometimes be a value, and sometimes be a type. This would also definitely complicate the Go spec since there is no other case when something like this occurs.

@ianlancetaylor
Copy link
Contributor

As @bcmills says, #21496 seems easier to understand, and as @deanveloper says, using the same name as both a type and a value has the potential to be quite confusing. We aren't going to make this change, but thanks for the suggestion.

@golang golang locked and limited conversation to collaborators May 30, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge LanguageChange Suggested changes to the Go language Proposal v2 An incompatible library change
Projects
None yet
Development

No branches or pull requests

6 participants