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

RFC: Exports on individual items (pub and priv) #1893

Closed
pcwalton opened this issue Feb 23, 2012 · 14 comments
Closed

RFC: Exports on individual items (pub and priv) #1893

pcwalton opened this issue Feb 23, 2012 · 14 comments
Assignees
Milestone

Comments

@pcwalton
Copy link
Contributor

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.

@marijnh
Copy link
Contributor

marijnh commented 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
Copy link
Contributor

+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
Copy link
Contributor

Also, I think we should use the same convention for classes.

@graydon
Copy link
Contributor

graydon commented 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:

  • Having all the exports listed in one place makes life easier on the reader visiting a module, figuring out what it does, looking for a summary of its interface. Yes, rustdoc can make a synopsis, but readers-in-emacs need to scan around for the entries marked pub.
  • Having all the exports listed in one place makes life easier for the module-author to think over what's being exported from a module "as an interface" and judge whether it's an appropriate set, has missing parts, has overlaps, has inconsistent naming, etc.
  • Writing 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 is public 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: and private: 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:

  • Change use to mean what import currently means, and rename use to link. Because use and import are too similar, and people don't really gather by looking that use means "link in this external crate"
  • Make the default no-qualifier status mean crate-local visibility (like package in java), make pub mean "exported from crate", and priv mean "private to this module and its inner scopes".

@pcwalton
Copy link
Contributor Author

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
Copy link
Contributor

graydon commented 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
Copy link
Contributor

brson commented Feb 26, 2012

How does this work with enum variants? Are they also crate-visible by default and require pub or priv to control their visibility? Currently they are public by default and we have a special form of export 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
Copy link
Contributor

graydon commented 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
Copy link
Contributor

graydon commented 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
Copy link
Contributor

assigning to @marijnh , but #1935 blocks this.

@marijnh
Copy link
Contributor

marijnh commented Apr 25, 2012

See also https://gist.github.com/2481106

@brson
Copy link
Contributor

brson commented Jul 9, 2012

punting to 0.4

@pcwalton
Copy link
Contributor Author

pcwalton commented Sep 6, 2012

This is working on incoming, except for cross-crate methods. Needs a snapshot to get rid of the old syntax.

@pcwalton
Copy link
Contributor Author

Closing; any remaining issues should be followups.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants