-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Closed
Milestone
Description
Instead of export
lists, we could have exports on individual items.
So, instead of:
fn foo() { ... }
export foo;
We would have:
pub fn foo() { ... }
And instead of:
import foo::bar;
export bar;
We would have:
pub import foo::bar;
(Here I changed export
to pub
to better match classes and to avoid exceeding the 5-character limit, but I'm ok either way.)
This change would help avoid the pain of managing export lists and should make libraries easier to write. Often people look at the definitions of items and want to know then and there whether the item is public or not.
Metadata
Metadata
Assignees
Labels
No labels
Type
Projects
Milestone
Relationships
Development
Select code repository
Activity
marijnh commentedon Feb 23, 2012
I'm in favour of this. Scrolling back and forth to the export list at the top of the file to keep things consistent is painful and error-prone.
Also, this might nicely generalize glob exports --
pub import foo::*;
.nikomatsakis commentedon Feb 23, 2012
+1 from me. I would also like it if things were private by default in all cases, just for simplicity. (As opposed to "if there are no pub declarations, then everything is pub")
nikomatsakis commentedon Feb 23, 2012
Also, I think we should use the same convention for classes.
graydon commentedon Feb 24, 2012
@marijnh It does generalize export globs, yes. That's more or less how I've modified the resolve pass to treat export globs anyways. Merged the glob-specifying AST nodes and just treats an export glob as "an import of the same kind that happens to re-export its target".
I'm not completely in favour of this, but partly. It's similar to how I did things at first; I changed to the current system for these reasons:
pub
.pub
as a qualifier at the definition site makes definition sites chattier. When you mention Java's verbosity one of the first phrases on people's lips ispublic static void main
. So I've been shy about qualifier-bloat, particularly one that's mandatory or really common.pub fn main() { ... }
is not so bad, but it's a step in that direction.I realize these are in direct tension with the desire to avoid flipping up-and-down between definitions and export lists though. So I'm just .. curious if there's some way to relieve that tension.
Some languages "solve" this by using sectioning directives within definition scopes. That is, the way C++ members are organized into any number of
public:
andprivate:
sections. Ada does something similar inside its packages (http://en.wikibooks.org/wiki/Ada_Programming/Packages). I wonder if there's something worth exploring in there?As an aside, I think if we make this change we should bundle it with two other changes:
use
to mean whatimport
currently means, and renameuse
tolink
. Becauseuse
andimport
are too similar, and people don't really gather by looking thatuse
means "link in this external crate"package
in java), makepub
mean "exported from crate", andpriv
mean "private to this module and its inner scopes".pcwalton commentedon Feb 24, 2012
Having all the exported symbols live in one place is nice, but the problem is that only the identifiers, not the signatures, live there. So in practice one ends up scrolling down to find the definition anyway.
I think I'm ok with crate-local visibility being the default.
pub {}
blocks are an interesting idea. I don't like item-level chattiness either. Labeled sections like C++ (pub:
) are kind of hostile to macros, but nestable blocks seem doable.graydon commentedon Feb 25, 2012
Yeah. What you say wrt. signatures is true. I find the export-lists only moderately helpful as a synopsis. They're no function prototypes.
I'm certainly willing to experiment with this and see how it looks.
(Resolve is due for a reorganization anyways, I think. But maybe that is orthogonal to this.)
brson commentedon Feb 26, 2012
How does this work with enum variants? Are they also crate-visible by default and require
pub
orpriv
to control their visibility? Currently they are public by default and we have a special form ofexport
for them. I think I would prefer them to stay public by default, but then there's not a keyword to make them crate-visible.graydon commentedon Feb 28, 2012
Maybe have them default to the visibility of their declaring enum, with explicit overriding permitted? We'd need the keyword for crate-visible in that case, as you say (I realize this is slightly widening the scope of this RFC), but perhaps
crate
?graydon commentedon Mar 6, 2012
At meeting, had consensus to implement this (pub, priv, crate) access-control on items, and turn export into import + access control.
catamorphism commentedon Apr 13, 2012
assigning to @marijnh , but #1935 blocks this.
marijnh commentedon Apr 25, 2012
See also https://gist.github.com/2481106
Start parsing pub/priv on regular items
14 remaining items