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: add tag support when declaring types and functions/methods #15398

Closed
urandom opened this issue Apr 21, 2016 · 6 comments
Closed

proposal: add tag support when declaring types and functions/methods #15398

urandom opened this issue Apr 21, 2016 · 6 comments
Labels
FrozenDueToAge LanguageChange Suggested changes to the Go language Proposal
Milestone

Comments

@urandom
Copy link

urandom commented Apr 21, 2016

Currently tags are only supported on struct fields, which is somewhat limiting. This proposition is to add tag support when defining types and functions/methods.

When declaring a type, a tag may optionally be specified after the type itself:

TypeSpec     = identifier Type [ Tag ] .

As for functions and methods, the signature may hold the tag:

As it is necessary to somehow get these tags with reflection, and the only proper place is to add a Tag method to the reflect.Type interface, this unfortunately pushes the proposal to 2.0 land (unless reflect.Type is somehow not covered by the compatibility promise). The Tag method of the Type interface should return a type similar to StructTag (or StructTag, renamed to Tag for 2.0). The ast package must also be extended to support reading these tags, to be useful for code generator tools and the like.

Since struct tags are heavily used in go already, adding them for other types will not introduce confusion. Even more, they could solve a lot of current problems. For example, quite a few code generator tools currently rely on comments to find out what they need to do. With this addition, they could use the tags directly, which is more idiomatic. Marshaler libraries (such as json) can use it to get extra information about what they need to do. That will also cover #15314 and #15230 (which gave rise to the idea of this proposal in the first place), without the need to add more specialized functions/methods. A final example for functions and methods is a common case with web frameworks that have to restrict certain handlers to authenticated users only. Such a case may be solved by using tags on these functions and methods, with the underlying framework, or http router, or middleware using the information to decide what to do.

@ianlancetaylor ianlancetaylor added this to the Proposal milestone Apr 22, 2016
@ianlancetaylor
Copy link
Member

This proposal does not necessarily have to wait for 2.0. We can not remove methods from reflect.Type, but we can add them.

That said, I do not understand your web framework example. Struct tags let us convey information that is separate from the type, which is useful when the same type is used in many different ways. A web framework that supports different authentication mechanisms could do so through the type anyhow. It doesn't need an additional mechanism. The types passed into a web framework are unlikely to be used in any other way, so requiring them to be a specific type doesn't seem a significant hardship.

Also, adding tags to a type requires you to have a specific type. If you have to have a specific type anyhow, adding a method doesn't seem like a big deal. Tags would be somewhat more concise, but they don't seem to provide any functionality that is not already available. If there were a way to put a tag on a specific instance of an existing type, that would be a different matter--that is what field tags let you do--but it doesn't seem to be what you are proposing.

@urandom
Copy link
Author

urandom commented Apr 23, 2016

Yeah, at the time I didn't realize that specifying tags on functions would inevitably place those tags in the value, instead of the type. Which is not what I am proposing. So the part about them should be ignored.

@extemporalgenome
Copy link
Contributor

@ianlancetaylor since reflect.Type is an interface, adding methods would certainly break any alternative implementations of that interface.

@ianlancetaylor
Copy link
Member

@extemporalgenome The Go 1 compatibility guidelines permit us to add methods to types, though it doesn't discuss interface types. So I guess the situation is unclear. In any case, if necessary, we could add methods to reflect.rtype and define new interfaces that permit people to access those methods via interface conversion from reflect.Type.

@bradfitz bradfitz added the LanguageChange Suggested changes to the Go language label Aug 29, 2016
@adg
Copy link
Contributor

adg commented Aug 29, 2016

Another way of achieving this would be to implement a method like this:

func (T) Metadata() string { return "some metadata here" }

In fact, one advantage here is you could have structured data, not just a string tag:

type Metadata struct {
  A string
  B int
}

func (T) Metadata() Metadata { return Metadata{A: "foo", B: 1} }

It is also more efficient than looking up the tag with reflect.

@adg
Copy link
Contributor

adg commented Oct 3, 2016

Given that there's a viable workaround and no other support for this proposal, I'm going to decline it. Thank you.

@adg adg closed this as completed Oct 3, 2016
@golang golang locked and limited conversation to collaborators Oct 3, 2017
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
Projects
None yet
Development

No branches or pull requests

6 participants