Commands in comments

4,085 views
Skip to first unread message

Marcus Holmes

unread,
Dec 23, 2014, 12:20:50 AM12/23/14
to golan...@googlegroups.com
Apologies if this has been brought up before... you wouldn't believe how many topics you have to sort through if your keyword is "comment" ;)

I know this won't be possible in the near future (<v2), but can the golang team consider a different method of including these commands than in comments?

I have two objections:
1. Theoretical: Comments are comments, not instructions. Making some comments do stuff breaks the idea of comments.
2. Practical: the difference between // go:generate and //go:generate is not obvious and it's not immediately clear that one is an extremely powerful command and the other is just a comment that can be safely ignored -especially when text editors don't know the difference and syntax-colour them both the same.

What I'd like to see is a separate delimiter for the commands (maybe '#', though that has its own problems). The go compiler treats them as comments, while the other processes ignore conventional "//" and "/*" comments (so you can comment out a command) and only look for the special delimiter.


Brad Fitzpatrick

unread,
Dec 23, 2014, 12:28:57 AM12/23/14
to Marcus Holmes, golang-dev
I agree it's unfortunate and the syntax is overloaded. You're right that this isn't something that can be fixed soon.

Not that this is complete, but there are more:

package foo // import "foo.com/foo"   (https://golang.org/s/go14customimport)
//go:linkname
//go:generate
//go:cgo_import_static
//go:cgo_import_dynamic
//go:cgo_ldflag
//go:noescape
//go:nowritebarrier
//go:nosplit

At least most start with "//go:" ! :)



--
You received this message because you are subscribed to the Google Groups "golang-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-dev+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

minux

unread,
Dec 23, 2014, 12:30:22 AM12/23/14
to Marcus Holmes, golang-dev
This has been discussed in the go:generate proposal thread, IIRC.

The short answer is: the convention is now "//go:xxx" prefix is for magic comments.
the only exceptions are: // +build, //line, and the import comment.

Manlio Perillo

unread,
Dec 23, 2014, 8:43:47 AM12/23/14
to golan...@googlegroups.com, mfhh...@gmail.com
Il giorno martedì 23 dicembre 2014 06:28:57 UTC+1, Brad Fitzpatrick ha scritto:
I agree it's unfortunate and the syntax is overloaded. You're right that this isn't something that can be fixed soon.

Not that this is complete, but there are more:

package foo // import "foo.com/foo"   (https://golang.org/s/go14customimport)
//go:linkname
//go:generate
//go:cgo_import_static
//go:cgo_import_dynamic
//go:cgo_ldflag
//go:noescape
//go:nowritebarrier
//go:nosplit

At least most start with "//go:" ! :)

What about having them start with `//! `?
This is the same hack used to specify the executable for a shell script (shebang).

As an example:
//! go:awesome

> [...]

Regards  Manlio Perillo

Brad Fitzpatrick

unread,
Dec 23, 2014, 11:50:07 AM12/23/14
to Manlio Perillo, golang-dev, Marcus Holmes
Remember that suggestion for when Go2 planning happens and propose it then. Nothing's changing here until then.

Manlio Perillo

unread,
Dec 24, 2014, 5:54:34 AM12/24/14
to golan...@googlegroups.com, manlio....@gmail.com, mfhh...@gmail.com
Il giorno martedì 23 dicembre 2014 17:50:07 UTC+1, Brad Fitzpatrick ha scritto:

> [...] 

At least most start with "//go:" ! :)

What about having them start with `//! `?
This is the same hack used to specify the executable for a shell script (shebang).

Remember that suggestion for when Go2 planning happens and propose it then. Nothing's changing here until then.


Unless I'm wrong, since they are just comments, it should be easy to support both the old and the new syntax,
and go fix should be able to update old code.

What I fear with the new "//go:" syntax is that alternate Go implementations will start to do something like
"//gccgo:"
"//llgo:"
"//gopherjs:"

The problem is that a tool has no way to identify a command, so when a future go2 will
add, as an example, special syntax support for commands, go fix will be unable to fix code, and
these external tools will break.

Regards  Manlio

minux

unread,
Dec 25, 2014, 2:18:39 AM12/25/14
to Manlio Perillo, golang-dev, mfhh...@gmail.com
On Wed, Dec 24, 2014 at 5:54 AM, Manlio Perillo <manlio....@gmail.com> wrote:
What I fear with the new "//go:" syntax is that alternate Go implementations will start to do something like
"//gccgo:"
"//llgo:"
"//gopherjs:"

The problem is that a tool has no way to identify a command, so when a future go2 will
add, as an example, special syntax support for commands, go fix will be unable to fix code, and
these external tools will break.
You probably don't know that even before introducing any of "//go:" magic comments, alternative
compilers already invented their own magic comments.

For example, gccgo has "//extern", and llgo supports "//extern" as well as its own namespaced
attributes comment "//#llgo "

The introduction of "//go:linkname" actually helps to unify some of the existing magic comments,
because "//extern" is a strict subset of "//go:linkname".

Russ Cox

unread,
Jan 7, 2015, 12:18:08 PM1/7/15
to Manlio Perillo, golang-dev, mfhh...@gmail.com
On Wed, Dec 24, 2014 at 5:54 AM, Manlio Perillo <manlio....@gmail.com> wrote:
What I fear with the new "//go:" syntax is that alternate Go implementations will start to do something like
"//gccgo:"
"//llgo:"
"//gopherjs:"

That is exactly why the syntax is //go: and not //!, so that it is clear who the comment is talking to.
If gccgo needs to add specific comments, it can go right ahead and use //gccgo: and everyone else will ignore them.
 
 The problem is that a tool has no way to identify a command, so when a future go2 will
add, as an example, special syntax support for commands, go fix will be unable to fix code, and
these external tools will break.

The way to avoid this migration problem is not to migrate. The existing comment format is good. There's no reason to change it and thus no need to migrate it.

Russ

Marcus Holmes

unread,
Jan 7, 2015, 6:06:29 PM1/7/15
to golan...@googlegroups.com, manlio....@gmail.com, mfhh...@gmail.com
Agreed, that if we have to put commands in comments the system currently doing this is OK

But I disagree that putting commands in comments *at all* is a good idea. Just because other languages do it doesn't make it a good idea. It's clearly a hack to get around some historical problem, and we're better than that.

minux

unread,
Jan 7, 2015, 6:10:08 PM1/7/15
to Marcus Holmes, golang-dev, Manlio Perillo
On Wed, Jan 7, 2015 at 6:06 PM, Marcus Holmes <mfhh...@gmail.com> wrote:
But I disagree that putting commands in comments *at all* is a good idea. Just because other languages do it doesn't make it a good idea. It's clearly a hack to get around some historical problem, and we're better than that.
Unless we designed the spec from the start to envision these extensions,
I don't think we have choices other than to put them into comments.

Ian Lance Taylor

unread,
Jan 7, 2015, 6:51:28 PM1/7/15
to Marcus Holmes, golan...@googlegroups.com, Manlio Perillo
On Wed, Jan 7, 2015 at 3:06 PM, Marcus Holmes <mfhh...@gmail.com> wrote:
>
> But I disagree that putting commands in comments *at all* is a good idea.
> Just because other languages do it doesn't make it a good idea. It's clearly
> a hack to get around some historical problem, and we're better than that.

If it makes you feel better, think of the magic comments as pragmas.
They do, after all, have a specific syntax.

I don't really agree that it is an attempt to get around an historical
problem. We use magic comments for two purposes. One is to indicate
a special but unusual feature of a function. The comments like
//go:cgo_export_dynamic are of this form. They are not quite part of
the language, since they don't affect how the code works. But they do
need to be recognized by the compiler because they mean that the
associated function requires special treatment at link time.

It seems clear to me that it's better that this kind of directive be
present in the Go source near the symbol that it affects. In C/C++
the similar idea of symbol versioning started out as a separate input
file to the linker but was soon transmogrified into directives that
can appear in the source code (rather hideous directives that are
normally hidden by preprocessor macros). If we accept that, then we
could implement this using some sort of pragma syntax, but in the
absence of a preprocessor a magic comment syntax supports all required
features. So it boils down to a matter of taste.

The second use of magic comments is things like +build and
go:generate: directives that apply to tools used to build Go code.
These directives tend to apply to an entire file. It would be
possible to use some sort of metadata file that the appropriate tool
could examine. But it's not clear why that is better. Again, I think
it is a matter of taste.

Ian

Marcus Holmes

unread,
Jan 7, 2015, 8:30:11 PM1/7/15
to golan...@googlegroups.com, mfhh...@gmail.com, manlio....@gmail.com
I agree that these kinds of commands need to be in the source code.
I agree that they need some kind of symbol to flag to the language compiler that they should be ignored
I agree that the symbol should be the only thing specified by the compiler (so that other tools can use their own syntax with their commands)

I disagree that the comment symbol should be used for this purpose
// and /*-*/ are specifically for comments. If we were designing a language from scratch we would not be happy with dual-purposing these symbols so that sometimes they're completely harmless and can be removed without side-effects and sometimes they actually have powerful effects on the code, and there's no way of determining which.

All I propose is that we use a different symbol to indicate non-compiler commands. Let's assume we use "#" for this (I'm not suggesting we do, unless everyone's comfortable with being able to shebang go source files).
so:
// this is a comment - it will always be ignored by everything and is purely human-human communication in the code
# this is a command for some other tool apart from the go language compiler. It should not be removed but will be ignored by the compiler.
/*
  # this is a command that has been commented out and will be ignored by other tools
*/
//# also works to do this

that's my suggestion anyway.

Andrew Gerrand

unread,
Jan 7, 2015, 8:35:13 PM1/7/15
to Marcus Holmes, golang-dev, manlio....@gmail.com

On 8 January 2015 at 12:30, Marcus Holmes <mfhh...@gmail.com> wrote:
If we were designing a language from scratch

But we're not doing that, and it's not going to change now.

Andrew

Dave Cheney

unread,
Jan 7, 2015, 8:36:12 PM1/7/15
to Marcus Holmes, golang-dev, Manlio Perillo
Marcus,

The use of things like //go:noescape and the _few_ other instances is
restricted (by convention) to a very small part of the standard
library. They aren't used widely in Go code, in fact I bet very few
people who have not read the standard library even know they exist.
They are not documented because they are not part of the language,
only an artefact of the current gc implementation.

Similarly // +build is not part of the language either, it is an
instruction to help the build tool, cmd/go, which isn't part of the
language either.

I don't think there is a problem here, I don't understand why you are
so worked up about this.

Dave

Andrew Gerrand

unread,
Jan 7, 2015, 8:38:21 PM1/7/15
to Dave Cheney, Marcus Holmes, golang-dev, Manlio Perillo

On 8 January 2015 at 12:36, Dave Cheney <da...@cheney.net> wrote:
I don't think there is a problem here, I don't understand why you are
so worked up about this.

I didn't interpret Marcus' messages as being particularly heated.
I think we just have to agree to disagree.

Andrew

Marcus Holmes

unread,
Jan 7, 2015, 8:54:01 PM1/7/15
to golan...@googlegroups.com, da...@cheney.net, mfhh...@gmail.com, manlio....@gmail.com
indeed :) please don't take this as criticism of the fine work going on here, and I apologise if my tone appears heated. Purely intellectual interest I assure you :)

I've always questioned the use of comments for non-commentary purposes, it seems like such an inelegant hack. But if everyone's fine with it then my sensibilities are clearly off and I'll go away muttering to myself ;)

minux

unread,
Jan 7, 2015, 9:06:27 PM1/7/15
to Marcus Holmes, golang-dev, Manlio Perillo
On Wed, Jan 7, 2015 at 8:30 PM, Marcus Holmes <mfhh...@gmail.com> wrote:
I agree that these kinds of commands need to be in the source code.
I agree that they need some kind of symbol to flag to the language compiler that they should be ignored
I agree that the symbol should be the only thing specified by the compiler (so that other tools can use their own syntax with their commands)

I disagree that the comment symbol should be used for this purpose
// and /*-*/ are specifically for comments. If we were designing a language from scratch we would not be happy with dual-purposing these symbols so that sometimes they're completely harmless and can be removed without side-effects and sometimes they actually have powerful effects on the code, and there's no way of determining which.

All I propose is that we use a different symbol to indicate non-compiler commands. Let's assume we use "#" for this (I'm not suggesting we do, unless everyone's comfortable with being able to shebang go source files).
so:
// this is a comment - it will always be ignored by everything and is purely human-human communication in the code
# this is a command for some other tool apart from the go language compiler. It should not be removed but will be ignored by the compiler.
/*
  # this is a command that has been commented out and will be ignored by other tools
*/
//# also works to do this
This will be language change, and as I've said, the spec does not have has
this, so we can't change it now.

Except for // +build and // import, which is meant for cmd/go, most magic
comments have one thing in common: there is no space between // and
the first character ('g'). I think it's as good as introducing a new special
character as you've proposed, because normally people will add a space
after "//" for real comments.

Lucio De Re

unread,
Jan 8, 2015, 12:15:12 AM1/8/15
to Marcus Holmes, golan...@googlegroups.com, da...@cheney.net, manlio....@gmail.com
On 1/8/15, Marcus Holmes <mfhh...@gmail.com> wrote:
> I've always questioned the use of comments for non-commentary purposes, it
> seems like such an inelegant hack. But if everyone's fine with it then my
> sensibilities are clearly off and I'll go away muttering to myself ;)
>
I think the point you made about being able to drop ALL comments
without impacting the meaning of the source file is significant here.
It may be a matter of taste, but it also happens to be a decision that
needs to be made early in the design of a language and one that sticks
around for a very long time.

I manually entered the entire P4 source once, a very long time ago
(that was Niklaus Wirth's Pascal compiler) and even there, comments
were being used to influence the compiler's behaviour (sigh!).

Lucio.

Russ Cox

unread,
Jan 8, 2015, 11:45:53 PM1/8/15
to Marcus Holmes, golang-dev, Manlio Perillo
On Wed, Jan 7, 2015 at 6:06 PM, Marcus Holmes <mfhh...@gmail.com> wrote:
But I disagree that putting commands in comments *at all* is a good idea. Just because other languages do it doesn't make it a good idea. It's clearly a hack to get around some historical problem, and we're better than that.

Where you see a hack I see an elegant design. We'll just have to disagree.

Russ

Dmitri Shuralyov

unread,
Jan 9, 2015, 11:26:20 PM1/9/15
to golan...@googlegroups.com, mfhh...@gmail.com, manlio....@gmail.com
I would just like to visualize the current decision/state of Go in a table format:

|                                                    | Syntax            | Space after comment beginning                |
|----------------------------------------------------|-------------------|----------------------------------------------|
| Code for compiler                                  | not //, not /* */ | -                                            |
| Documentation for humans                           | // or /* */       | Yes typically (but not enforced)             |
| Disabled code (aka temporarily commented out code) | // or /* */       | No typically (but not enforced)              |
| Executable commands for non-compiler               | // or /* */       | No (enforced for most commands, but not all) |
Reply all
Reply to author
Forward
0 new messages