Type tags, in addition to struct (field) tags?

472 views
Skip to first unread message

Matt Sherman

unread,
Dec 4, 2013, 10:03:04 AM12/4/13
to golan...@googlegroups.com
Struct (field) tags have proven very useful, and I am curious whether there has been consideration of offering the same at the type level? Would be handy for the stuff I am doing on gen.

Not sure where it would go syntactically, but something along the lines of:

type Thing struct `tag:"thing"`
{
    Field1 int `tag:"stuff"`
}

type Another []string `tag:"foo"`

A bit of metadata would go a long way. Could apply to any type def, not just structs. Was there a particular design decision to only support struct fields?

Rob Pike

unread,
Dec 4, 2013, 10:54:31 AM12/4/13
to Matt Sherman, golan...@googlegroups.com
Tags were put in to support transport metadata for structs, to avoid
needed an external IDL for JSON, XML, protocol buffers and so on. They
have indeed been useful but they also result in noisy-looking code and
encourage a weak and clumsy kind of metaprogramming. It's telling that
they're only visible through the reflection interface.

I would be reluctant to extend their reach.

-rob

Gustavo Niemeyer

unread,
Dec 4, 2013, 11:03:29 AM12/4/13
to Matt Sherman, golan...@googlegroups.com
On Wed, Dec 4, 2013 at 1:03 PM, Matt Sherman <mwsh...@gmail.com> wrote:
> Struct (field) tags have proven very useful, and I am curious whether there
> has been consideration of offering the same at the type level? Would be
> handy for the stuff I am doing on gen.
>
> Not sure where it would go syntactically, but something along the lines of:
>
> type Thing struct `tag:"thing"`

If you're already parsing Go code, you can use comments for that kind of thing:

//gen thing
type Thing struct { ... }


gustavo @ http://niemeyer.net

Ugorji Nwoke

unread,
Dec 4, 2013, 11:20:21 AM12/4/13
to golan...@googlegroups.com
I had this same requirement for my codec library and I solved it by defining a private field within the struct and assigning tags to it. E.g.

type Thing struct {
  __struct struct{}  `tag:"thing"`
  Field1 int
}

This works well for me. It's unexported, so you don't lose anything.

Matt Sherman

unread,
Dec 4, 2013, 1:28:25 PM12/4/13
to golan...@googlegroups.com
Ugorji, that's an interesting approach, may try that.

Rob, thanks for the explanation. Good point about arbitrary text morphing into a bad programming language.

- Matt

Kevin Gillette

unread,
Dec 5, 2013, 12:20:37 AM12/5/13
to golan...@googlegroups.com
If we pretend that the proposal (and proposed syntax) were universally favored, it'd result in an inconsistent grammar. Consider:

// the brace must go on the same line as the tag
// unless a special (inconsistent) exception were made

type Thing struct `tag:"thing"` {
    Field1 int `tag:"stuff"`
}
type Integer int `tag:"other thing"`

In the above, the tag in the struct case goes after the struct keyword. For primitive types, it'd Go after the type definition. Really, the only consistent approach is to put the tag after the entire type definition, and that'd result in:

type Thing struct {
    Field1 int `tag:"stuff"`
} `tag:"thing"`

That looks a bit like typedef's in C, and typedef'd structs are pretty ugly.

Matt Sherman

unread,
Dec 8, 2013, 8:00:41 PM12/8/13
to golan...@googlegroups.com
I went with the comment approach here, seems to work: http://clipperhouse.github.io/gen/#Subsetting
Reply all
Reply to author
Forward
0 new messages