-
Notifications
You must be signed in to change notification settings - Fork 18.4k
Description
What version of Go are you using (go version)?
1.13
Does this issue reproduce with the latest release?
What operating system and processor architecture are you using (go env)?
N/A, is proposed change
What did you expect to see?
Periodically, the question comes up of wanting some way to have sub-scopes, or to access file scope. (#7429 points out that file scope sort of exists, you just can't use it much).
The basic use case is: You want a thing to live inside a package, not in another package, because you want access to the package internals, but you have your own Even More Internals that you don't want exposed to the rest of the package -- possibly simply because you don't want to worry about name clashes.
For an example of the kind of workaround that exists, consider this example:
https://play.golang.org/p/WAuGTEHwiPg
This seems reasonable-ish, but it creates a subtle problem: I don't think the compiler can inline method values, and there's no other way I can see to get a function that you can call directly that knows about an implicit context it has which is a distinct namespace. (The lack of inlining hardly matters for some things, but for some performance-critical stuff on hot paths, it'd probably be bad.)
I have a definitely-unusable proposal for this, but don't see how to fix it. I am gonna go ahead and file this, because maybe someone will see an obvious fix, and if not, hey, every time someone asks for file-scope access, you can point them at this.
Proposal:
Just as capital letters represent exported names, and lowercase indicate unexported names, _ as the first character of an identifier is even more lowercase, and indicates a name which is only valid within the source file containing the declaration.
Problems with the proposal:
- No way to disambiguate the names if two files in the same package declare the same name. And names can leak; you could have two files provide identically-named implementations of an interface.
- Existing code uses
_as a prefix already. (Although a quick check through the go corpus suggests that it's never used to refer to - Possibly a bad idea to add another source of complexity.
But I have thought about all the things like adding namespaces or modules or whatever that I've seen used to address this, and I think they all fundamentally run into "this is too hard to think about and requires too much context to interpret", while a variable naming convention allows you to see the thing instantly. And I've seen larger things run into problems with difficulty making sure names don't clash with each other within a package, but not want (or be able to) split the package cleanly.
A working solution might involve some other character. Someone in the performance channel on gopher slack suggested (jokingly) using unicode subscripts. I could also imagine \ being repurposed but I'm pretty sure everyone would hate that, and anyway lots of Go programmers are old enough to know that \u is actually an uppercase u. @?