So it's possible that a future version of Go could add a field to some struct you're using and your code will stop compiling when you upgrade. It's an easy fix, of course, so it's not that big of a deal, but it's worth realizing.
I'm explicitly rejecting the idea that all struct changes should be possible without producing compiler errors. Compilers errors when the guarantees your code is based on changes is a feature, not a bug.
Compiler errors aren't evil. They're a tool. They work best when there is a one-to-one correspondence between problems and errors. That's not possible in the general case, but the closer we get, the better. And the worst case is not when I get a spurious error. That's easy to deal with. The worst case is when I don't get an error I should have. If you're going to worry about "riskiness", that's the risk that should keep you up at night. Not compiler errors for things that turn out to be no big deal, and can quite likely be fixed with one quick go fmt -s.
With keyed-fields, the worst case is that you have uninitialized fields, which typically doesn't cause much problems and get caught quickly where it matters. With unkeyed-fields, you might have code that compiles but sets unexpected fields. Things that would otherwise panic, now just keep working without you noticing, until strange things happen and you have to review all initializations and remember the struct layout every time you see the struct being created.
Personally, I don't like both techniques anyways. It's too error prone. I'll prefer writing a small constructor where I handle initialization deliberately. It's not super Go-ish but at least I centralize all the issues surrounding struct initialization in 1 place: the constructor. Then when I change what fields go in the struct, I change the function signature and the compiler breaks and doesn't let things fall through silently.
You can also see this in how all the dynamic languages are working on adding "optional" or "incremental" dynamic typing. Static languages, by contrast, generally create one dynamic type, stick it in a library somewhere, and let the small handful of people who really need it use it. Few, if any, of them are adding any dynamic features. The motion trends are clear.
And the noob that is so noobish that they change code and don't even compile it to check to see whether it works is a menace well beyond this issue. That's an overpowerful argument; the real problem is the noob that isn't even running the compiler. The noob doesn't "break struct initializations" specially, they break everything.
The choice in question is whether I want code that breaks silently when I add a field to a struct (named fields in initializers), or code that breaks silently when I swap fields of the same type in a struct (positional fields in initializers). Please tell me more about how "judgment ability" makes this anything other than a choice between brittle code and brittle code.
> And the noob that is so noobish that they change code and don't even compile it to check to see whether it works is a menace well beyond this issue. That's an overpowerful argument; the real problem is the noob that isn't even running the compiler. The noob doesn't "break struct initializations" specially, they break everything.
Compilation will not catch all situations where struct fields are reordered. Consider the rather common case where two fields on a struct are of the same type. If a noob swaps the order of these fields, it will compile just fine using your method of struct initialization. It's even quite possible that if unit tests initialize the structs in the same way, this could get past unit tests as well.
This is a pretty obvious case, and the fact that I have to explain it to you is yet another example of having to dumb things down for Go users who don't know the first thing about programming language design.
Or perhaps even the even more complicated case I already mentioned upthread, that an int will still happily initialize a float?
"Consider the rather common case where two fields on a struct are of the same type. If a noob swaps the order of these fields, it will compile just fine using your method of struct initialization. It's even quite possible that if unit tests initialize the structs in the same way, this could get past unit tests as well.... dumb things down for Go users"
What does any of this have to do with Go? All languages with structs have these "problems"! Even Haskell will have the exact same problems (even before you turn on OverloadedStrings). You're reaching so hard to be dismissive of some sort of stereotypical programmer that only exists in your head that you've completely surrendered reason. You should reconsider whether that's really who you want to be.
I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question. We're discussing ways of initializing Go structs.
> All languages with structs have these "problems"!
This is completely false, and exactly why I'm dismissing you: we wouldn't be having this conversation if you knew anything about other languages. There are plenty of languages which will warn you when you fail to initialize a struct field when initializing fields by name.
In this case, if you used:
most future type changes to the T struct will become compiler errors. (It won't be if the types are compatible, for instance, changing the first to a float would still result in a legal struct. If you have richer types in play that is less of an issue.)golint will then complain at you, but you can pass a command-line switch to turn that off.
(This, amusingly, puts me in the rare position of siding against the Go community, on the side of the language designers. Bet you may not have known there is such a position to take. :) )