Remix.run Logo
omoikane 11 hours ago

I wonder why they chose to add these directives as comments as opposed to adding new syntax for them. It feels like a kludge.

https://wiki.c2.com/?HotComments

kjksf 11 hours ago | parent | next [-]

Go designers distinguish between Go language as defined by Go spec and implementation details.

//go:fix is something understood by a particular implementation of Go. Another implementation could implement Go without implementing support for //go:fix and it would be a fully compliant implementation of Go, the language.

If they made it part of the syntax, that would require other implementations to implement it.

bheadmaster 11 hours ago | parent | next [-]

That's such an elegant solution.

I keep being impressed at subtle but meaningful things that Go does right.

dwattttt 11 hours ago | parent | prev [-]

If the comments impact correctness (which inlining doesn't, but I believe there are other directives that do), saying it's "an implementation detail" waves away "it's an implementation detail that everyone needs" aka part of the spec.

The reason it feels like a kludge is that "comments" are normally understood to be non-impactful. Is a source transformation that removes all comments valid? If comments have no impact per the spec, yes. But that's not the case here.

In practice comments in go are defined to be able to carry semantic meaning extensibly. Whether they're safe to ignore depends on what meaning is given to the directives, e.g. conditional compilation directives.

scheme271 5 hours ago | parent | next [-]

There are directives and packages that affect correctness. E.g. the embed package allows you to initialize a variable using a directive. E.g. //go:embed foo.json followed by var jsonFile string initializes the jsonFile variable with the contents of the foo.json file. A compiler or tooling that doesn't support this results in broken code.

tptacek 10 hours ago | parent | prev | next [-]

There's nothing unique to Go about this kind of tooling. It exists in C, Java, Rust, Typescript, and probably dozens of other settings as well. It's the standard way of implementing "after-market" opt-in directives.

dwattttt 10 hours ago | parent | next [-]

Are we referring to 'go fix' as after market tooling?

It's certainly done in many places. JsDoc is the biggest example I can think of. But they're all walking the line of "this doesn't have an impact, except when it does".

It being done by the language owners just makes them the ones walking the line.

tptacek 10 hours ago | parent [-]

That's exactly how this works: it doesn't have an impact, except when you ask it to. This is an idiomatic approach to this problem.

dwattttt 9 hours ago | parent [-]

The part I object to is overloading comments, which aren't meant to be load bearing. A tool developed outside the language has no choice but to take something that has no meaning and overload it, but language owners weren't forced to take this route; they could've made directives not comments.

In practice, the Go language developers carved syntax out of comments, so that a comment is "anything that starts with //, unless the next characters are go:"

YesThatTom2 8 hours ago | parent [-]

So how many angels can you fit on the head of a pin?

omoikane 9 hours ago | parent | prev | next [-]

In the listed examples, the compiler will emit a diagnostic upon encountering those comments:

https://go.dev/blog/inliner#example-fixing-api-design-flaws

So these comments carry more weight than how those comment annotations might be consumed by optional tools for other languages.

For most of the listed examples, I think the corresponding C annotation would have been "[[deprecated]]", which has been added to the syntax as of C23.

ternaryoperator 9 hours ago | parent | prev | next [-]

It does not exist in Java. Comments in Java do not change code.

9rx 3 minutes ago | parent | next [-]

It doesn't exist in Go either. https://go.dev/ref/spec

That's why you find it in the comments. That is where third-party tools can add their own syntax without violating the expectations of the Go language.

joshuamorton 8 hours ago | parent | prev [-]

This also does not change th code. It is an advertisement to a linter-loke tool to take some action on the source code. Its most similar to linter directives which usually are comments.

TheDong 4 hours ago | parent [-]

We're talking about the "//go" comments in general I think here.

Things like "//go:embed" and "//go:build" very much do change the semantics of source code.

The comments above 'import "C"' containing C function definitions and imports change the compilation of go source code.

The "//go" comments contain a mix of ones that must be respected to compile, to being optional, to being entirely ignorable (like generate and fix).

Patryk27 9 hours ago | parent | prev [-]

There are no comment-based directives in Rust, are there?

win311fwg 8 hours ago | parent | next [-]

It provides the feature to use. It’s possible nobody has yet.

tptacek 9 hours ago | parent | prev [-]

Eh, you're right, they have a structured attribute system.

joshuamorton 10 hours ago | parent | prev [-]

> The reason it feels like a kludge is that "comments" are normally understood to be non-impactful. Is a source transformation that removes all comments valid? If comments have no impact per the spec, yes. But that's not the case here.

This is not inlining in the compiler. It's a directive to a source transformation (refactoring) tool. So yes, this has no impact on the code. It will do things if you run `go fix` on your codebase, otherwise it won't.

dwattttt 10 hours ago | parent [-]

And yet it still breaks "comments aren't semantic". That transformation I described is still invalid.

pastel8739 8 hours ago | parent [-]

I don’t understand why that wouldn’t be valid. As far as I understand if you compile code with these go:fix comments, they will be ignored. But if instead of compiling the code you run ‘go fix’, the source code will be modified to inline the function call. Only after the source code has been modified in this way would compiling reflect the inlining. Do you have a different understanding?

dwattttt 8 hours ago | parent [-]

I mean that directives other than inlining impact correctness. If you have a source file that only builds for one OS, stripping the build tag will break your build.

kalterdev 3 hours ago | parent | prev | next [-]

I suppose, to minimize its use. If annotations have the same syntactic weight as normal statements, such as “if” or “for” statements, there’s a temptation to use them liberally, which is clearly not a good fit for Go.

By making them comments, Go subtly signals that these are exceptional, making them less prominent and harder to abuse.

Groxx 9 hours ago | parent | prev | next [-]

Because these are instructions for users for making tool-assisted changes to their source code, not a behavior that exists at runtime (or even compile time). A new syntax wouldn't make sense for it.

For other things, like `//go:noinline`, this is fair criticism. `//go:fix inline` is quite different in every way.

0x696C6961 11 hours ago | parent | prev [-]

The //go:xyz comments are an established pattern in the Go tooling.

Mond_ 11 hours ago | parent [-]

This is begging the question. Yes, but why did they do that over dedicated syntax?

(My personal theory is that early go had a somewhat misguided idea of simplicity, and preferred overloading existing concepts with special cases over introducing new keywords. Capitalization for visibility is another example of that.)

6 hours ago | parent | next [-]
[deleted]
thwarted 11 hours ago | parent | prev [-]

//go:xyz is dedicated syntax that is compatible with both the language spec and other toolchains that don't know about it.

4 hours ago | parent | next [-]
[deleted]
debugnik 39 minutes ago | parent | prev | next [-]

Good luck compiling on a toolchain that doesn't know about //go:embed or /* */import "C" comments.

Mond_ 10 hours ago | parent | prev [-]

It's an overloaded comment. I am personally quite fine with it, I don't think it's bad. but it is an overloaded comment.

thwarted 9 hours ago | parent [-]

I'm no longer sure what you're saying. You asked why they didn't go with dedicated syntax, I listed two advantageous aspects of the chosen syntax. We know it's an overloaded comment: that's literally one of the advantages.

Mond_ 6 hours ago | parent [-]

Well, I've been unable to follow you as well, then. Obviously if they'd used a different type of syntax (e.g. using # for annotations), those would also be compatible with the language spec, and other implementations would still be just as capable of ignoring all unknown annotations.

(Though for the record, talking about alternative implementations when discussing Go is kind of a funny joke.)

overfeed 3 hours ago | parent [-]

Is gccgo a joke to you?

debugnik 24 minutes ago | parent [-]

Maybe? It's stuck in 1.18 without generics and no one has replaced its maintainer, Ian Lance Taylor, who seems to have moved on after leaving Google.

But to be fair to alternatives toolchains, TinyGo and TamaGo are also a thing.