The vast majority of the issues with the current system seem to boil down to: “Doctor, it hurts when I do this.” “Well, don’t do that.” Obviously, that’s the cynical view.
One of the things I like about the current module system is that you have to be redundant. Redundancy is important in programming language design because if you remove all redundancy, you get machine code. Every possible input is valid, thereby reducing size, but you have no way of checking if what is being executed is what was intended.
One of the things that really is confusing in Rust is name lookup. ::std::
vs std::
, in the crate root vs in a submodule. The privacy system is also confusing. This proposal doesn’t seem to fix name lookup at all. And the privacy aspects of the system like pub(crate)
and pub(self)
seem to work independently of the other aspects of the proposal. Granted, I’m not very familiar with the recent pub(restricted)
stuff, so it’s possible I’m missing something here.
One possible solution that would be explicit (which I like) and solve a lot of boiler plate (which I don’t like, as well) is inline namespaces (C++). If you wrote inline mod foo;
it could behave as though foo
didn’t exist and import the contents of foo
into it’s containing module. This would result in the futures
module looking like:
inline mod and_then;
inline mod flatten;
inline mod flatten_stream;
inline mod fuse;
inline mod into_stream;
inline mod join;
inline mod map;
inline mod map_err;
inline mod from_err;
inline mod or_else;
inline mod select;
inline mod select2;
inline mod then;
inline mod either;
This results in almost the exact same behavior you describe. If you want the code in another file, add a single line of code with the name of the file.
- Private items would be private to the file, just like your proposal.
-
pub(self)
would make it accessible to the containing module. -
pub(crate)
would make it accessible to the entire crate. -
pub
would make it accessible to the parent of the containing module.
And note, pub inline mod foo;
doesn’t make sense because foo
isn’t introduced as a name into any scope. (This would be unlike C++'s inline namespaces.)
And I don’t think this has any backwards compatibility concerns.
Edit:
Oh, and the PAL stuff can be:
#[cfg(...)]
inline mod unix;
#[cfg(...)]
inline mod windows;
And it doesn’t matter whether it’s a single file or a folder structure.
The more I think about it, the more I realize that your proposal is effectively a subset of this proposal. In your proposal, files are implicitly inline mod foo;
while directories are pub mod foo;
or mod foo;
depending on whether they start with _
. Your proposal doesn’t have a way to have non-inline files or inline directories. It also has backwards compatibility issues.
(Note, I could be missing something, after all, it is 4am and I only started thinking about this an hour ago.)