Skip to content

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

@pcwalton

Description

@pcwalton
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.

Activity

marijnh

marijnh commented on Feb 23, 2012

@marijnh
Contributor

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

nikomatsakis commented on Feb 23, 2012

@nikomatsakis
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

nikomatsakis commented on Feb 23, 2012

@nikomatsakis
Contributor

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

graydon

graydon commented on Feb 24, 2012

@graydon
Contributor

@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

pcwalton commented on Feb 24, 2012

@pcwalton
ContributorAuthor

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

graydon commented on Feb 25, 2012

@graydon
Contributor

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

brson commented on Feb 26, 2012

@brson
Contributor

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

graydon commented on Feb 28, 2012

@graydon
Contributor

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

graydon commented on Mar 6, 2012

@graydon
Contributor

At meeting, had consensus to implement this (pub, priv, crate) access-control on items, and turn export into import + access control.

ghost assigned on Apr 13, 2012
catamorphism

catamorphism commented on Apr 13, 2012

@catamorphism
Contributor

assigning to @marijnh , but #1935 blocks this.

marijnh

marijnh commented on Apr 25, 2012

@marijnh
Contributor
added a commit that references this issue on May 8, 2012

14 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Relationships

None yet

    Development

    No branches or pull requests

      Participants

      @graydon@marijnh@brson@nikomatsakis@pcwalton

      Issue actions

        RFC: Exports on individual items (pub and priv) · Issue #1893 · rust-lang/rust