Skip to content
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: Go 2: explicit exports #30572

Closed
hdante opened this issue Mar 4, 2019 · 11 comments
Closed

proposal: Go 2: explicit exports #30572

hdante opened this issue Mar 4, 2019 · 11 comments
Labels
FrozenDueToAge LanguageChange Proposal v2 A language change or incompatible library change
Milestone

Comments

@hdante
Copy link

hdante commented Mar 4, 2019

Add support for explicitly exporting symbols with an export keyword instead of implicitly exporting upper case symbols.

package package1

export (
    symbol1
    symbol2
    Symbol3
)

func symbol1() {
}

(...)

Why ?

The main motivation is allowing to export lower case symbols [edit 20190304: and non latin scripts #22188]. Secondary motivation is to have a more fine grained export control.

My opinion on current state is that golang forces usage of camel case and mixed case coding styles (not really true in theory but true in practice). I don't like using mixed case both due to personal reasons (I think it's ugly) and technical reasons (it tends to break case sensitive searches, which I think are better suited for code than case insensitive searches), and I very much prefer using coding styles analogous to Python's PEP8[1].

Suggested implementation

There are two approaches, one is compatible with go 1 and another breaks compatibility.

  1. Compatible with go 1: if there's no top-level export keyword, then symbol exporting works exactly like in go 1. If there's a top-level export keyword, then symbol exporting only exports explicit symbols.

  2. Incompatible with go 1: all exports must become explicit.

In any case, implementation would work with a new top level parsed element that would replace current (constant) export logic with a table search.

Extras

Export wildcards:

export all uppercase
export all lowercase
export a*
(etc.)

References

[1] https://www.python.org/dev/peps/pep-0008/

@gopherbot gopherbot added this to the Proposal milestone Mar 4, 2019
@dotaheor
Copy link

dotaheor commented Mar 4, 2019

This decreases the readability.
We can use the export keyword elsewhere. For example, I use the export keyword in my generics proposal to export some elements from a gen. A gen can be viewed as mini-package.

@hdante
Copy link
Author

hdante commented Mar 4, 2019

This decreases the readability.

Agreed, it slightly decreases readability. So the proposal is a compromise. A good one, I believe, that's why I proposed it.

We can use the export keyword elsewhere. For example, I use the export keyword in my generics proposal to export some elements

I'm definitely not bikeshedding over a keyword name and I'm sorry I've stolen export from your proposal. So here we go:

provide (
    symbol1
)

from a gen. A gen can be viewed as mini-package.

I'm not sure if you're suggesting this proposable is replaced by a generic mini-package (whatever that might mean), but if so I disagree. This proposal is neither about generic nor mini-packages, it's about full featured packages.

@bcmills bcmills added LanguageChange v2 A language change or incompatible library change labels Mar 4, 2019
@bcmills
Copy link
Contributor

bcmills commented Mar 4, 2019

The main motivation is allowing to export lower case symbols.

See also #22188.

@bcmills bcmills added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Mar 4, 2019
@hdante
Copy link
Author

hdante commented Mar 4, 2019

The main motivation is allowing to export lower case symbols.

See also #22188.

Agreed and will edit proposal motivation.

@robpike
Copy link
Contributor

robpike commented Mar 4, 2019

Speaking just for myself, I have spent a long time worrying about this general topic and doing research about it. So have others. And I have concluded it's not worth fixing, if indeed it's broken at all. The clarity of the current rules, not only in their expression but also in their use in the source code of the package but also, perhaps more important, the source code of the user's code, is just too high to compromise here.

Using case to distinguish export status is one of Go's most radical but most important features. The huge positive effect on readability is profound.

@ianlancetaylor ianlancetaylor removed the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Mar 4, 2019
@ianlancetaylor
Copy link
Contributor

@bcmills note that for Go 2 proposals only the Go 2 proposal review group should add NeedsFix or NeedsInvestigation labels. They are how we track the state of proposals. Thanks.

@hdante
Copy link
Author

hdante commented Mar 4, 2019

Speaking just for myself, I have spent a long time worrying about this general topic and doing research about it. So have others. And I have concluded it's not worth fixing, if indeed it's broken at all. The clarity of the current rules, not only in their expression but also in their use in the source code of the package but also, perhaps more important, the source code of the user's code, is just too high to compromise here.

Disagreed. Comparing it with pretty much every other language, I think it's a very slight readability decrease and a pretty small compromise. I think the export status of a symbol within a package is mostly searched when refactoring the API, otherwise it's just directly used without additional concerns, while outside the package finding a symbol requires reading the docs or source code, both of which would have an explicit export section in this case.

but also, perhaps more important, the source code of the user's code, is just too high to compromise here.

I didn't understand here. In user's code, to use imported symbols they must be of exported type. There's no choice here. What do you mean ?

Using case to distinguish export status is one of Go's most radical but most important features. The huge positive effect on readability is profound.

Disagreed.

@beoran
Copy link

beoran commented Mar 15, 2019

In Oberon, from which git borrows much of the inspiration for it's module system, identifiers that are marked with * after them are exported. The issue #22188 and this one could be solved in a backwards compatible way, by allowing a similar marker in front of or perhaps after the identifier to export it, regardless of whether or not the following identifier is upper or lower case.

Ideally, this should only be used for Unicode identifiers in scripts that don't have the upper case and lower case distinction, but that is a policy that go vet could check, not something that the compiler would have to enforce.

@UFOXD
Copy link

UFOXD commented Mar 16, 2019

@robpike
Using case to distinguish export status is one of Go's most radical but most important features. The huge positive effect on readability is profound.

I do not think so.

@beoran
Copy link

beoran commented Mar 21, 2019

@robpike I agree that using case to distinguish export status is a great feature of Go.

However, seeing #22188, and also this issue, I think that we need a way to make an exception to this general rule and allow certain identifiers that do not begin with an uppercase character to be exported. An Oberon like marker seems the simplest, most backwards compatible way to do this.

@ianlancetaylor
Copy link
Contributor

This and alternative suggestions were considered extensively in the early days of Go. We seem to have made a choice that at least for most people is working well. We aren't going to change it now.

@golang golang locked and limited conversation to collaborators Mar 25, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge LanguageChange Proposal v2 A language change or incompatible library change
Projects
None yet
Development

No branches or pull requests

8 participants