Use path::<turbo, fish> as name

Examples:

// For generic types
use std::collections::BTreeMap::{
  <u32, (String, u32, u32)> as People,
  <u32, (String, u32)> as Companies,
  <u32, (String, u32)> as Resident, 
};

// For generic functions
use crate::create_pair::<u32, String> as create_string_pair;

// For generic trait methods
use std::convert::From::<usize>::from as from_index;

That's doable today:

use std::collections::BTreeMap;

type People = BTreeMap<u32, (String, u32, u32)>;
type Companies = BTreeMap<u32, (String, u32)>;
1 Like

That's only for generic types. What about generic functions and methods?

And if it is possible with functions and methods, I think a unified, consistent syntax would improve the language.

Well, what about them? They work equally well with let et al.

There's no value in adding more mere redundancy to the language for the sake of saving a couple keystrokes.

let binding is only valid within a function. I cannot share them for multiple functions.

Eventually you'll be able to write

const create_string_pair: impl Fn(u32, String) -> Pair<u32, String> = crate::create_pair;

at the top level, which creates a way to alias monomorphizations of functions.

We already want to be able to do use Trait::method, because we'd like to be able to expose a free fn default<T: Default>() -> T that's just pub use Default::default.

Being able to use monomorphizations of types/functions is also interesting from another point of attack: compile work reuse.

We'd love for crates providing generic types to be able to precompile some monomorphizations of the abstractions and let downstream reuse those compilation artifacts rather than re-monomorphizing the same application of type parameters in every downstream crate. If a library provider can [pub] use a generic type as a concrete one, that provides a lightweight way to create (and expose) a concrete monomorphization of the generic type for the compiler to reuse in dependents.

Note that use wouldn't replace type. Any used name would have to be "fully" applied and not have any more generic parameters left (except for Self in the case of trait methods). type would still be uniquely useful for type aliases that are still (partially) generic.

That said, I think we could also benefit from a fn analogue for type where it would be possible to write something to the effect of fn create_numbered_pair<T> = create_pair<usize, T> the same way you can with type (which I believe even does the same for the implicit tuple struct constructor function now as well).

11 Likes

This line is long enough that I would prefer to provide generic arguments directly.

I don't think I'd want to see this embedded in a long braced use statement; it seems confusing to me to mix type aliases with imports.

I'd rather see type alias syntax used for this.

8 Likes

Also note the possibility to have type inference usable on non public consts:

const create_string_pair: _ = crate::create_pair::<u32, String>;

That would allow to use const as the value equivalent of type, very much in line with generic type parameters and const generics.

It would also allow to avoid the issue that @josh pointed out, since use statements would remain limited to item paths.

2 Likes

What about this:

#[monomorphized(use_as="People", types="<u32, (String, u32, u32)>")]
#[monomorphized(use_as="Company", types="<u32, (String, u32)>")]
...
use std::collections::BTreeMap;

I don't know whether this is possible by using proc macros; if it is not, this would be my RFC candidate. If it is, someone in the thread knows how to do this can write a macro crate to make this happen.