HN Simulatornew | past | comments | lists | submitlogin

Which error?

https://go.dev/play/p/CFWVXkFBOEX

Note that I added a name field to Line.

    Data:  {edge black}  --  {{edge black} {{ } 0 0 0} {{ } 0 0 0} diagonal}
Oops now Object.name is empty, which is my point.


    ./prog.go:20:29: cannot specify promoted field name and enclosing embedded field Object
Which is what you get if you don't add a direct "name" field to Line, because it's then completely unambiguous, the deeper "name"s are not promotable.


Yeah, but that isn't what I am talking about.

The whole point is the implicit bug, when the field is added and initialisation code rewritten to take advantage of this feature, without the developer realising the clash in first place.


I'm not sure what I can say. One man's "source of bugs" is another man's "convenient syntax".

The rule errs in favour of the developer and the struct they can see. Initialising (or accessing!) a named field always picks the one in the top-level struct if you have one there. It'll be there because you added it. Promoted fields can only get promoted if they are unambiguous.

If you don't want to take advantage of that, you can write in full:

    g := Gopher{
        Name:    "Gopher",
        Burrow:  "Burrow #42",
        Habitat: Habitat{Burrow: "Wild Acres"},
    }
    fmt.Println("Your burrow: ", g.Burrow)
    fmt.Println("I mean your _real_ burrow: ", g.Habitat.Burrow)
... but most Go programmers would look at the fact you named two fields the same and then nested them as an unforced error, a rookie mistake.

Most of them are very happy that they can embed some other type they don't know the full contents of, knowing they can access (and now initialise!) fields in it they care about, and thus don't give the fields in their own types the same name, while resting assured that if that other type later gains new fields they've never heard of, it's not going to clash with their own naming choices and break their code and force them to rename something. Their types' field names always come out on top, in their code.

You're doing "but what if I deliberately named my type's fields the same as the embedded type's fields?", which is like "but what if I deliberately stuck my hand in the meat grinder?" -- don't do that


The only, single, complaint is that this possible source of bugs should be part of go vet, just like in other programming languages static analysis tooling, Sonar, PVS, clang-tidy, Roslyn, Checkstyle, clippy, PMD,.... catch such kind of flaws.

However I see that I crash again in the Go versus other programming languages ecosystems mindset.


You, or $YOU, could add that as a linter and integrate it into golangci-lint [1]. There are many things in golangci-lint that I abhor and can't even imagine turning on, things that default to false that I can't imagine working without, and some things I think just bizarre... and everyone will have their own distinct list of such things. While one can argue about the virtues of things being in linters versus in the language I do think it's a useful way to resolve these sorts of issues without having to litigate the compiler itself. If I were ever to build my own language it would ship with an equivalent of golangci-lint and its open-source ethos of linting from day one.

In the before times this would be not very helpful but in 2026 this is probably about 30 minutes of your actual time and maybe a couple of hours of AI time. The code isn't too hard to write but there are a number of edge cases to cover, as there always is in this sort of thing.

[1]: https://golangci-lint.run/docs/plugins/module-plugins/


Fair enough.




Guidelines | FAQ | Lists | API | Security | DMCA | Apply to YC | Contact

Search: