Apologies, this is my first email of the morning, with all the pedantry and over-arguing for no good reason that implies. I've tried to keep it brief but partly it's just a factor of time. Turn the mood-filter to "not really as grumpy as this sounds", if possible :(

On 12/09/2012 7:36 AM, Patrick Walton wrote:
So instead of:

     extern mod std;
     use std::json::Json;

You'd write:

     use std::json::Json;

The semantics of this would be that names of external crates form a sort
of "outer namespace" one level higher than the root of the crate being
compiled. Equivalently, it could be understood as "if regular resolution
of a module fails, try to load a crate". This would only work for "use"
statements; explicitly-namespace-qualified identifiers would not be
eligible for this magic.

This is what Python does, and it seems to work quite well for them.

Thoughts?

Not too keen, as-written. There might be something in this space we can do, say 'use std = (<matchers>);' or something, but even that feels like a toss-up in terms of clarity (see point 3 and footnote [1] below).

As written it suffers from three things that make me uncomfortable:

  - Abandons the distinction between short-name lookup and metadata
    matching. I know most of our testcases just said "use foo;" before
    but anything for deployment or major reuse really ought to be using
    metadata matching so it's somewhat robust against installation in
    an environment with more than one thing called 'foo'. Also, we've
    some (vague) plan to shift the package management scheme to using
    matchers as URL sources for installing missing crates, and that
    vanishes.

  - Contravenes the explicit-is-better-than-implicit principle. Readers
    don't know (and can't see) where the crate-dependencies are.

  - Breaks the two-fold symmetry with other uses of 'extern' and other
    uses of 'mod foo = ...'; I actually think this is quite a compact
    factoring where the meanings fall out naturally from the code:

      mod foo = "foo.rs"      // compile-in other .rs files
      extern { ... }          // link-to non-rust, declared symbols[1]
      extern mod foo = <matchers>;   // link-to external rust code
      extern mod foo;                // short DWIM-form for same

In general I'm a bit wary of optimizing this case too hard for ultimate brevity. The 'use' directive that shows up a lot in programs is the one managing the internal namespace. The linkage directives are few and far between, and should usually all reside in one top-level file that is barely ever opened or changed[2].

I really think the 'short programs' case shouldn't motivate design choices. Truly short programs -- one-liners or the sort that wind up on website front pages and might scare users off if too chatty -- just link with libcore anyways, which is implicitly linked. Real crates can't get by with tiny DWIM-y utterances because they need to be precise (and offer information about URLs, versions, crate-wide compilation settings, etc.)

I mean, I know we're "getting rid of crate files", in the sense of eliminating the file-type distinction in favour of a couple special syntactic forms, but in any nontrivial crate, top-level files with similar amounts of chatter are very likely going to take their place. Take a look at these:

   https://github.com/mozilla/rust/blob/master/src/cargo/cargo.rc
   https://github.com/mozilla/rust/blob/master/src/libstd/std.rc

I don't know that there's a way around it. If we don't write some of this stuff down _somewhere_, it winds up in Makefiles, and then we have two (well, like, 10) problems.

-Graydon

[1] As an aside about a 3rd possible use of 'extern', given that we need _some_ word for this role in a couple contexts (the old uses of 'crust' and 'native'), it's occurred to me that it might also recycle 'extern' for the putative 'package-level export' we've sometimes talked about. That is, 'pub' and 'priv' carry on meaning what they mean _within_ a crate, but the question of whether a symbol is exposed for linkage from _outside_ a crate could be predicated on the word 'extern', with the default being 'anything pub', but overridden by explicit declarations.

[2] Indeed, I'm still struggling with the issue of whether to re-enforce a limit on where linkage declarations can even occur, so that the compiler / package manager can _scan_ for them all without having to run the entire front-end and elaborate any macros / evaluate all the attributes. Initially 'use' directives were only allowed in crate files, for just this reason, but that restriction vanished sometime around the transition to declaring native-mods in separate files, killing off the crate-evaluation phase and adding in conditional attributes. Still, where we are presently is worrying; the compiler can't tell what it's going to want to link until very late in the game.
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to