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: spec: file and package scope interact in odd ways #7429

Open
griesemer opened this issue Feb 27, 2014 · 4 comments

Comments

@griesemer
Copy link
Contributor

commented Feb 27, 2014

This is just a reminder to revisit the interactions between file and package scope at
some point in the future.

At the moment we have the following rule:

"... no identifier may be declared in both the file and package block." (
http://tip.golang.org/ref/spec#Declarations_and_scope )

The reason for this rule is that we don't want to, say, import package math, and also
have a - in the same file - a package level variable math, and the import would then
hide the variable because the file block is inside the package block, and not have any
visible nesting (in fact the nesting is "inside out" in this case).

However, as a consequence, other odd behavior follows. Assume a package p consisting of
two files a.go, b.go, with a.go importing package math, and b.go not importing anything.

In b.go, the identifier math is not visible (it is in a.go's file scope), yet it is not
possible to declare a package-level variable math in b.go w/o an error because of the
above-cited rule. This is counter-intuitive.

One could imagine an alternative approach that satisfies the same intent, namely avoids
that both an import of an identifier x hides a package-level identifier x in the same
file:

- File blocks are nested inside the package block as before.
- Each import and also each top-level declaration in a file go into the file block.
- Additionally, each non-imported identifier also goes into the package block.

This way, all non-imported top-level identifiers are visible in all files. Imports
remain only visible in the file containing the import. Imports and file-level
declarations cannot conflict (this is the main purpose of the above rule).

Implementation-wise there may be different approaches to obtain the desired behavior. A
direct implementation of these new rules might lead to the (possibly undesired) property
that non-import file-level declarations end up both in a compiler's file and package
scope, that is, an object belongs to two scopes simultaneously.

The new rules would be a backward-compatible language change.
@cznic

This comment has been minimized.

Copy link
Contributor

commented Feb 28, 2014

Comment 1:

Also, not allowing to shadow the imported package qualifier is somewhat inconsistently
enforced only for TLDs: http://play.golang.org/p/77zRRbFxdI
Relaxing the current rules to allow a TLD named x in a file which doesn't use x as an
import qualifier even when some other file of the same package does would be IMHO an
improvement. The existing rule can eg. make some trouble when moving code between
packages, though probably not often.
Perhaps: "... no identifier may be declared in both the file and package block from
within the same source file"?
@griesemer

This comment has been minimized.

Copy link
Contributor Author

commented Apr 21, 2014

Comment 2:

Labels changed: added repo-main.

@griesemer griesemer self-assigned this Apr 21, 2014

@rsc rsc added this to the Unplanned milestone Apr 10, 2015

@rsc rsc removed release-none labels Apr 10, 2015

@go101

This comment has been minimized.

Copy link

commented Feb 25, 2017

no identifier may be declared in both the file and package block.

Why this? Any bad to make top level identifiers declared in both file and package blocks?
Just like the explanation in this article: http://www.tapirgames.com/blog/golang-block-and-scope ?
By thinking like this, it is consistent and easy to explain identifier shadowing.

@go101

This comment has been minimized.

Copy link

commented Feb 25, 2017

A direct implementation of these new rules might lead to the (possibly undesired) property
that non-import file-level declarations end up both in a compiler's file and package
scope, that is, an object belongs to two scopes simultaneously.

Aha, this is the same as the article mentioned above. I think this is a better approach.

The new rules would be a backward-compatible language change.

Need changes in go/* packages?

@rsc rsc changed the title spec: file and package scope interact in odd ways proposal: spec: file and package scope interact in odd ways Jun 20, 2017

@rsc rsc added the Go2 label Jun 20, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
6 participants
You can’t perform that action at this time.