-
Notifications
You must be signed in to change notification settings - Fork 17.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal: Go2: local/private to file #33202
Comments
This sounds like the problem that Internal packages solve. |
I would say that if a huge package is a mess, split it up into multiple packages. I don't see what we gain by adding another scoping level. When reading code it makes it harder to know which identifier is referred to. |
There is no strong support for this idea. It makes the language more complicated for minimal gain. Therefore, this is a likely decline. Leaving open for a month for final comments. |
When building an application, I believe it's not uncommon for a project to have one package (main) and divide it by subsystem using files. Naturally some identifiers in each file are only for use by that subsystem; they're often flagged with a naming convention, e.g. I do this regularly, so I see a rationale for this proposal. Dividing an application into separate packages is an unnecessary burden when none of the packages would be imported elsewhere. Also it may be necessary to use subsystem-local identifiers outside their intended scope for debugging. But there are alternatives to a language change... We could give go vet a way to recognize file-local identifiers. Would that be worth consideration? Only a tiny fraction of Go users follow the issue tracker, and perhaps many of them are focused on building open-source libraries, so it's not surprising to me that this issue has "no strong support" -- very few of the folks who might need it have heard about it. |
"No strong support" in this case means, at present, 1 vote in favor and 17 votes against, expressed as emoji on the initial post. Perhaps a better way to say it would be "overall support vote is negative." I agree that there is a rationale for this proposal. There is a rationale for every proposal. Nobody would make a proposal with no rationale. The question is whether it is worth the cost. |
I offered an alternative and posed a question:
By that I meant "project-specific file-local identifiers", e.g. a regular expression. Instead of "rationale", I should have said, "I see a large constituency for this feature, which is probably not well-represented among those who follow the issue tracker." |
What would it mean to have Also, note that this does not fall under the normal guidelines for |
Yes; and the "Internal packages" approach, while being theorically a solution, would require to split the package on many small packages which only one source file in each (like in my fictional database example above).
Well that's what I did so far, I coded a Perl script which analyses source files and finds out whether stuff in my packages use functions or types of other files of the same package which are below the placeholder line "// LOCAL PRIVATE BELOW".
But yes, adding the feature to |
go vet could take an argument of type regexp; any identifier matching the regexp would be flagged if used outside the file where it's defined.
Such identifiers would of course be unique across the package; that's not a problem. |
There were further comments since this was marked as a likely decline (#33202 (comment)) but they do not change our opinion. This should likely be a separate language checking tool for people who want to use it. -- for @golang/proposal-review |
A nice feature would be to ensure that an function/type/variable/constant is only usable in the current file (in addition of being private to the current package), and raise a compilation error if not.
A fictional (not necessarily good) example: I make a database package, with files like database_init.go, database_query.go and database_fetch.go. Each of these files have several functions and a some of them are configuration values or low-level helpers, like convertFieldToMyObject(f interface{}) in database_fetch.go, or like const connectionEndpoint="localhost:3306" in database_init.go. I don't want all these stuff to be used in any file, this can cause mistakes or at least reduce the file splitting coherence.
This two-levels encapsulation (package encapsulation and file encapsulation) would increase code quality. Without it, a "huge" package can become a mess.
To do this, the word "local" could be used, for example.
Note that by essence:
local var Foo = 3
would not compile (cannot be both public and local).
Another way to do it would be to have a line separator in a Go file like
===local===
orlocal:
with everything below this line until the end of file would be declared local, and everything above would be not. It's weirder and stricter, but I like it because it would ensure that non-local code remains on top of the file.The text was updated successfully, but these errors were encountered: