2015-07-02
Some thoughts on Go compiler directives being in source comments
Recently, I've been reading some commotion about how Go compiler directives being in source code comments is, well, not the 'elegant design' that Go's creators may feel it is. As it happens I have some sympathies for Go here, so let's talk about what I see as the issues involved.
First, let's differentiate between what I'll arbitrarily call 'broad'
and 'narrow' compiler directives. In a nutshell, what I'm calling
a broad compiler directive is something that changes the meaning
of the source code such that every compiler implementation must
handle it. In C, #include
and #define
are broad directives.
Broad directives are effectively part of the language and as such
I feel that they deserve first class support as an explicit element
in language syntax.
(Broad directives don't have to use a new language syntax element.
Python's 'from __future__ import ...
' is such a broad directive,
but it uses a standard language element.)
By contrast, narrow directives only apply to a specific compiler or tool. Since they're only for a specific program they should be namespaced, ie you need some way of saying 'this uninterpreted blob of text is only for <X>' so that other compilers can ignore it. This requires either a specific element of language syntax to say 'this following text is only for <X>' or hijacking a portion of some existing syntax where you can add arbitrary namespaced text. The easiest existing syntax to hijack is comments.
Since narrow directives do not change the language itself (at least in theory), it seems at least a bit odd to give them an explicit syntax element. In effect you're creating another escape hatch for language-meaningless text that sits alongside comments; one is sort of for people (although it may be interpreted by tools, for example for documentation) and one is a slightly structured one for tools.
(If a narrow directive changes the semantics of the code being compiled, it's actually changing the language the compiler is dealing with from 'language <X>' to 'something similar to <X> but not quite it'. Problems often ensue here in the long run.)
As far as I know, all of the existing Go compiler directives are
narrow directives. They're either used by specific non-compiler
tools or they're internal directives for one specific Go compiler
(admittedly the main 'go
' compiler). As far as I'm concerned this
makes them pretty much fair game to be implemented without a specific
element of language syntax. Other people may disagree and feel that
even narrow directives should have some sort of specific language
syntax support.
PS: There may well be standard terminology in the programming language community for what I'm calling broad versus narrow directives here.
(This elaborates on some tweets I made, because Twitter forces condensed and sometimes opaque writing.)
Sidebar: The problem with non-namespaced narrow directives
If you don't namespace your narrow directives you wind up with the
C #pragma
problem, which is 'what do you do when you encounter a
#pragma
that you don't recognize?'. If you do error out, you cause
problems for people who are using you to compile source code with
#pragma
s for some other compiler. If you don't error out, you
cause problems for people who've accidentally misspelled one of
your #pragma
s and are now having it be more or less silently
ignored.
(You can try to know about the #pragma
s of all other compilers,
but in practice you're never going to know absolutely all of them.)