As of the opening of this issue, import
statements can only be applied to a single module. This was due to convenience for the most part (easier to just ban all exprs and only allow identifiers than to allow exprs and add a warning for every unsupported case, especially when the support for them is coming soon), but there is an open question about how this should be enabled. Here are a couple of strategies, based on both Rust and Chapel.
{}
:This is how Rust handles that case. You put the greatest common module before the ::{
, and then can list any depth within the curly braces using additional ::
separators. For instance, for a module structure like this:
mod M {
pub mod Other {
pub mod N {
pub fn blah() {
use super::y;
y();
}
}
pub fn y() {
println!("Other y");
}
}
pub fn z(foo: i32) {
println!("M z");
println!("{}", foo);
}
}
you would write: use M::{z, Other::y, Other::N::blah};
. The equivalent version in Chapel based on our syntax would be import M.{z, Other.y, Other.N.blah};
This basically means that the only commas in Rust's use statements are within the curly braces.
Pros:
Cons:
{}
is provided:This is more in line with use
statements today. You'd only be allowed to write import M, M.Other;
or import M.{Other, this};
but not import M.{Other, this}, SomeOtherMod;
Pros:
import M.{x, y, this};
- could say import M, M.{x, y};
which might elide need for supporting this
in the curly bracesCons:
{}
:Because of the {}
, having a comma follow them is less ambiguous than it would be in the case of use statement's only
or except
lists, so theoretically we could get away with things like import M.{Other, this}, SomeOtherMod;
Pros:
Cons:
I'm currently in favor of, ultimately, permitting anything that can be specified as distinct import statements:
import <modExpr1>;
import <modExpr2>;
to be expressed as one using a comma as a separator:
import <modExpr1>, <modExpr2>;
Stylistically, I'd take the approach of using a separate line for each distinct module expression to aid with readability in the case that any of the expressions were complicated (e.g., used curly brackets):
import <modExpr1>,
<modExpr2>;
That said, I'm wanting this feature more for the case of using multiple unrelated modules:
import Random, List, IO;
than I am for the case of nested sub-modules and symbols, in which case I'd probably use curly brackets.
Brad clarified offline that the last comment would also include things like import M.x, M.y;
where x and y are non-module symbols defined within M. (which is pretty obvious reading it, but noting since I had forgotten)
My two cents: I am in favor of the last option "Allowing commas outside the {}".
In the example given there, I'd probably choose to separate those into two imports, but in my view it is a stylistic choice that shouldn't be imposed by the compiler, and it wouldn't bother me to some import statements like that. If it gets too complicated and the programmer doesn't do a good job of formatting that statement, it is just another instance of bad code formatting to me and not a syntax error.
Most helpful comment
My two cents: I am in favor of the last option "Allowing commas outside the {}".
In the example given there, I'd probably choose to separate those into two imports, but in my view it is a stylistic choice that shouldn't be imposed by the compiler, and it wouldn't bother me to some import statements like that. If it gets too complicated and the programmer doesn't do a good job of formatting that statement, it is just another instance of bad code formatting to me and not a syntax error.