Several people have mentioned that they are not happy with the
camelcase convention for module names. (I am actually among those
people.) A suggestion was made to go back to lowercase module names,
and to use different syntax for module dereferencing and
record/object/tuple dereferencing. If we follow Perl/C++ you'd get
std::vec::len(x). That way, module names an other names can be,
mostly, statically distinguished, and modules can live in a different
namespace from other names.
(I say mostly, because 'import foo::bar' is still ambiguous?is 'bar' a
module or a name? We could require 'import foo::bar::' in the former
case, or something like that.)
Working on the resolver has made me more sympathetic to this proposal.
I rather like the simplicity of std.vec.len, but it requires the
resolver to mangle the AST, since only at that stage is it clear
what's an expr_field. It'd be nice if the parser could handle this
without full knowledge about all used crates (also important for
external tools implementing 'jump to definition' and such).
So, I could
1) Implement this
2) Using our advanced transitional snapshot technology, follow up
said implementation with another monster commit that renames std
modules back to lowercase, and replaces all the right dots with the
new module dereferencing operator. (I think this can be done with some
creative regexping, since our set of module names is still rather
small, so I won't have to put the pretty printer into play yet)
One more thing I'd like to put out there: If we do something scary and
make a colon followed by an alphabetic character a different token
than one followed by something else, we can make the module
dereference operator a single ':'. I think our users will thank us, on
the whole, for the extra succinctness, but there is the issue of it
being slightly obscure -- you'll never even notice this rule when
writing well-formatted code, but then when, in a fit of naughtiness,
you omit the space in front of your typestate constraint, you'll get
an error. I think this is not a big problem, since your mistake will
be easy enough to figure out, but it's something to consider.
I went ahead an implemented a large part of this--using a single colon
as a module separator, and downcasing the module names again. A
separate module namespace isn't done yet. Look around
https://github.com/marijnh/rust/tree/modulesep if you're curious what
it looks like.
The thing is that this is going to bitrot faster than you can say
'please don't do this'. Graydon, I'm not sure how far the support for
transitional commits is, but even if it isn't there, you could, if you
agree with this, build the new compiler manually, register it as a
snapshot, and mark down the transitional snapshot in the file for
later. Please consider this an urgent pull request. (I'm of course
also okay with rejecting this, but do make up your mind before lots of
conflicting patches are merged.)
On 5/12/11 9:44 AM, Marijn Haverbeke wrote:
> I went ahead an implemented a large part of this--using a single colon
> as a module separator, and downcasing the module names again. A
> separate module namespace isn't done yet. Look around
> https://github.com/marijnh/rust/tree/modulesep if you're curious what
> it looks like.
I'd prefer ::, if for no other reason than that it's consistent with
C++, Ruby, PHP, and Perl. Also fewer special cases in the grammar are
always nice. Graydon can cast the deciding vote here :)
I always figured that "import foo::bar" or "from foo import bar" would
import both the "bar" item and the "bar" module if both exist. I don't
see much harm in that off the top of my head.
On 11-05-12 10:39 AM, Rafael Avila de Espindola wrote:
>> The problem is that this breaks the proposed separate namespace for
>> modules. If we don't know what bar is, we can't look it up.
> I like :: too.
> I am fine with any disambiguation option, or just declaring that import
> foo::bar is invalid if we find two bars.
Given the options I prefer a::b over a:b as well. Surveying IRC we also
had a vote from brson for ::, one from robarnold for :, and one from tjc
for initial-caps-as-module-namespace-indicator as in haskell. I think
the weight-o-votes favours ::.
It sounds like we're semi-converged on this design:
- We get 3 namespaces: types, modules and values.
- Module paths are separated by :: for similarity with
C++ (and Perl, PHP, Ruby)
- a.b in value context means a is a value
- a.b in type context is illegal
- a::b in type context means a is a module, b is a type
- a::b in value context means a is a module, b is a value
- import a::b imports all "b" bindings found in type, value or module
namespaces. we may modify this rule to permit selecting which of
the three you wish to import, but for now it seems harmless to
overload since all 3 referencing contexts are unambiguous.