# Improve \`use\` declarations

**URL:** <https://internals.rust-lang.org/t/improve-use-declarations/17425>\
**Category:** language design\
**Created:** [September 21, 2022, 10:46pm UTC](https://internals.rust-lang.org/t/improve-use-declarations/17425 "2022-09-21T22:46:02Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![JohnScience](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/johnscience/32/8970_2.png) [@JohnScience](https://internals.rust-lang.org/u/JohnScience)\
**Post date:** [September 21, 2022, 10:46pm UTC](https://internals.rust-lang.org/t/improve-use-declarations/17425/1 "2022-09-21T22:46:02Z")

</div>

Hi, use declarations are very convenient because they allow to clean up the code by opting-out from the path syntax.

However,

1. In default associated function implementation in traits the following is not permitted:

```rust
fn innate_armor(level: u8) -> u8 {
        use Self::{BASE_ARMOR, GROWTH};

        BASE_ARMOR + GROWTH * level
    }

```

e.g. in

```rust
struct Mage;
struct Swordsman;
struct Healer;

trait InnateArmor {
    const BASE_ARMOR: u8;
    const GROWTH: u8;
    fn innate_armor(level: u8) -> u8 {
        Self::BASE_ARMOR + Self::GROWTH * level
    }
}

impl InnateArmor for Mage {
    const BASE_ARMOR: u8 = 29;
    const GROWTH: u8 = 2;
}

impl InnateArmor for Swordsman {
    const BASE_ARMOR: u8 = 34;
    const GROWTH: u8 = 3;
}

impl InnateArmor for Healer {
    const BASE_ARMOR: u8 = 25;
    const GROWTH: u8 = 3;
}

fn main() {
    let (mia,sia,hia) = (
        Mage::innate_armor(15),
        Swordsman::innate_armor(15),
        Healer::innate_armor(15)
    );
    println!(
        "(29:34:25)->({}:{}:{})",
        mia,
        sia,
        hia,
    );
}

```

In such simple example, it's not too bad but I suppose that with more complex traits default implementations can be cleaned up by a lot.

EDIT: A person in the comment noted the case of using `Default::default()`. There's a library that offers such a feature but I'm unsure whether it's a good idea to reach for an external library in such a simple case.

1. Sometimes it's unclear which sort of item we (want to) import. With the pattern-designator-like syntax, we can provide better experience for readers of the code (especially, if there's IDE support, which may benefit the writers too due to better code suggestions).

```rust
use std::iter::{Empty,Once}:struct;
use std::borrow::{Cow}:enum;
use core::hash::{Hash}:trait;
// is it an enum, a struct, or a trait?
use my_crate::smth::Wtf;
// is it a function, a macro, or a module?
use another_crate::smth::parse;

```

The feature above can have some minor compile-time penalty, which may be justified by extra ~~readability~~ understandability of the code.

EDIT: even better syntax can be

```rust
use(enum) std::borrow::Cow;
use(trait) core::hash::Hash;
use(struct) std::iter::{Empty,Once};

```

which is similar to `pub(crate)` and is considerably cleaner.

Follow up questions.

- Should `type` refer to a type alias or an enum/struct, or maybe enum/struct/type alias? (I think, the latter).
- Will it be obvious for a reader coming from another language? (If it means an arbitrary type or type alias, I guess so).
- Would it be reasonable to reserve the `alias` keyword to make it obvious and support addition of trait aliases? (I think this is reasonable).
- Should `alias` keyword be context dependent, i.e. be a keyword only in this context? (I'm not sure because it will be the first context-dependent keyword in the language, which means its addition comes with greater complexity of the language).

Maybe something like

```rust
use(type alias) syn::Result;

```

and maybe eventually

```rust
use(trait alias) nalgebra::Vector;

```

What are your thoughts on this?

---

<div class="post-metadata">

**Author:** ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)\
**Post date:** [September 21, 2022, 10:48pm UTC](https://internals.rust-lang.org/t/improve-use-declarations/17425/2 "2022-09-21T22:48:46Z")

</div>

> [@Could we have \`std::default()\`?](https://internals.rust-lang.org/t/could-we-have-std-default/8756/2):
>
> I do wish it was possible to do something like use Default::default; so that when I say default it means Default::default…

---

<div class="post-metadata">

**Author:** ![JohnScience](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/johnscience/32/8970_2.png) [@JohnScience](https://internals.rust-lang.org/u/JohnScience)\
**Post date:** [September 21, 2022, 11:08pm UTC](https://internals.rust-lang.org/t/improve-use-declarations/17425/3 "2022-09-21T23:08:36Z")

</div>

Added another idea on use statement (explicit item kinds).

---

<div class="post-metadata">

**Author:** ![jkugelman](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jkugelman/32/8572_2.png) [@jkugelman](https://internals.rust-lang.org/u/jkugelman)\
**Post date:** [September 22, 2022, 9:22pm UTC](https://internals.rust-lang.org/t/improve-use-declarations/17425/4 "2022-09-22T21:22:48Z")

</div>

I agree that imports are unclear. It's particularly bad with:

- Macros since they lack the telltale `!`.
- Extension traits like `ReadExt` which don't list the methods being added, making it hard to grep for the source of an extension method.

Syntax bikeshedding, how about:

```rust
use enum std::borrow::Cow;
use trait core::hash::Hash;
use struct std::iter::{Empty, Once};
use std::pin::pin!;

```

---

<div class="post-metadata">

**Author:** ![JohnScience](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/johnscience/32/8970_2.png) [@JohnScience](https://internals.rust-lang.org/u/JohnScience)\
**Post date:** [September 22, 2022, 11:57pm UTC](https://internals.rust-lang.org/t/improve-use-declarations/17425/5 "2022-09-22T23:57:42Z")

</div>

- First, I'll address the proposed syntax for explicit item kind use declaration.

My greatest concern with the syntax without delimiters is that in C++ community [there were talks](https://www.youtube.com/watch?v=4AfRAVcThyA) about user-defined item kinds, user-defined keywords, user-defined notation.

 ![CppCon 2017_ Herb Sutter “Meta_ Thoughts on generative C++” 51-17 screenshot](https://us1.discourse-cdn.com/flex002/uploads/rustlang/original/2X/0/04a7689f06dfe7fd7bf24df1bfc89b885e9953ec.jpeg)

 ![CppCon 2017_ Herb Sutter “Meta_ Thoughts on generative C++” 60-56 screenshot](https://us1.discourse-cdn.com/flex002/uploads/rustlang/original/2X/7/70eb3b1752b405b1cd60cef66d4b0667025e9518.jpeg)

So it's future proof to expect that there can be arbitrary combinations of paths like `thirdparty::enum` and possibly context-dependent keywords. It's easier to assume that they can be complex than to hope that they aren't.

In addition, the syntax within parens should be easier to parse.

- Regarding macro, I wish I had idea how to unify their existing invocation syntax with the proposed syntax of their import. Right now, importing macros doesn't require a `!` (exlamation mark). It's understandable because punctuation-dense use declaration would look slightly awkward in my opinion.

```rust
use my_crate::{macro1!, macro2!};
use diff_crate::hello!;

```

In additon, this would separate macro exact item kind import from other exact item kind imports. For that reason I still prefer such import for function-like imports:

```rust
use(fn macro) diff_crate::hello;

```

though I'm still unsure regarding inner and outer attributes.

```rust
use(inner macro attr) no_discard;
use(outer macro attr) feature;

```

because the code above is quite mouthful.

- I also remember disliking the fact of possible collisions within associated items. Especially, for traits. You can sort of deal with it by resorting to fully-qualified path syntax but it's mouthful and ugly.

So far I have no idea how to make a clean syntax for that.

---

<div class="post-metadata">

**Author:** ![jkugelman](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jkugelman/32/8572_2.png) [@jkugelman](https://internals.rust-lang.org/u/jkugelman)\
**Post date:** [September 23, 2022, 1:07am UTC](https://internals.rust-lang.org/t/improve-use-declarations/17425/6 "2022-09-23T01:07:30Z")

</div>

> [@JohnScience](#):
>
> So it's future proof to expect that there can be arbitrary combinations of paths like `thirdparty::enum` and possibly context-dependent keywords.

Can you draw the line between that talk and this discussion? I'm not seeing the connection.

> [@JohnScience](#):
>
> In addition, the syntax within parens should be easier to parse.

`use struct` et al are already easy to parse. `struct` isn't allowed in paths and it's not connected to the path with `::` so the syntax is unambiguous. Parentheses aren't necessary and just add visual noise in my opinion.

> [@JohnScience](#):
>
> - It's understandable because punctuation-dense use declaration would look slightly awkward in my opinion.
> 
> ```rust
> use my_crate::{macro1!, macro2!};
> use diff_crate::hello!;
> 
> ```

Those look quite nice to me.

---

<div class="post-metadata">

**Author:** ![jkugelman](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jkugelman/32/8572_2.png) [@jkugelman](https://internals.rust-lang.org/u/jkugelman)\
**Post date:** [September 23, 2022, 1:20am UTC](https://internals.rust-lang.org/t/improve-use-declarations/17425/7 "2022-09-23T01:20:31Z")

</div>

This reminds me of an insight one of the Rust language members had\[1\]: our tendency when designing new syntax is to make it really noisy. It's new and unfamiliar and we feel like it should really stand out. The `?` operator is a good example. Many people thought the ugliness of `try!(...)` was a virtue and strongly opposed the unobtrusive `?`.

Over time, as we get used to a feature, we want it to blend in better, recede into the background. We're all used to `?` now, and I doubt many people would want to revert to `try!`.

That's what `use(inner macro attr) no_discard;` makes me think of. It draws way too much attention to itself.

* * *

1. Josh? Niko? I can't remember who said it or where they said it. I'd love a citation if anybody has one.

---

<div class="post-metadata">

**Author:** ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)\
**Post date:** [September 23, 2022, 5:00am UTC](https://internals.rust-lang.org/t/improve-use-declarations/17425/8 "2022-09-23T05:00:48Z")

</div>

> [@jkugelman](#):
>
> This reminds me of an insight [...]

That's _Stroustrup's Rule_: [Stroustrup's Rule and Layering Over Time](https://www.thefeedbackloop.xyz/stroustrups-rule-and-layering-over-time/)

---

<div class="post-metadata">

**Author:** ![anon32976453](https://avatars.discourse-cdn.com/v4/letter/a/49beb7/32.png) [@anon32976453](https://internals.rust-lang.org/u/anon32976453)\
**Post date:** [September 23, 2022, 5:56am UTC](https://internals.rust-lang.org/t/improve-use-declarations/17425/9 "2022-09-23T05:56:39Z")

</div>

> [@scottmcm](#):
>
> That's _Stroustrup's Rule_: [Stroustrup's Rule and Layering Over Time](https://www.thefeedbackloop.xyz/stroustrups-rule-and-layering-over-time/)

Quite ironic given that C++ values backwards compatibility above all else and (almost) never deprecates or removes anything.

It's not a good or valuable design principle in practice imo and has high transition costs that should be avoided if possible.

---

<div class="post-metadata">

**Author:** ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)\
**Post date:** [September 23, 2022, 6:01am UTC](https://internals.rust-lang.org/t/improve-use-declarations/17425/10 "2022-09-23T06:01:21Z")

</div>

> [@anon32976453](#):
>
> It's not a good or valuable design principle in practice imo

It's an observation about what people _ask_ for, not a recommendation for how to design things.

---

<div class="post-metadata">

**Author:** ![anon32976453](https://avatars.discourse-cdn.com/v4/letter/a/49beb7/32.png) [@anon32976453](https://internals.rust-lang.org/u/anon32976453)\
**Post date:** [September 23, 2022, 11:57am UTC](https://internals.rust-lang.org/t/improve-use-declarations/17425/11 "2022-09-23T11:57:13Z")

</div>

Fair enough. I merely observed that C++ seems to apply this layering approach to its design which results in suboptimal design and accidental complexity. Latest example is the co\_\* keywords for control flow in coroutines.

Let's get back on topic - the above suggested "improvement" is not a good idea imo. I rather not add all this redundant line noise.

Instead, we could look at static imports in Java for inspiration.

---

<div class="post-metadata">

**Author:** ![JohnScience](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/johnscience/32/8970_2.png) [@JohnScience](https://internals.rust-lang.org/u/JohnScience)\
**Post date:** [September 23, 2022, 2:04pm UTC](https://internals.rust-lang.org/t/improve-use-declarations/17425/12 "2022-09-23T14:04:06Z")

</div>

> [@jkugelman](#):
>
> Can you draw the line between that talk and this discussion? I'm not seeing the connection.

Theoretically, the kind of the imported item can eventually be user-defined and imported from some path.

> `use struct` et al are already easy to parse. `struct` isn't allowed in paths and it's not connected to the path with `::` so the syntax is unambiguous. Parentheses aren't necessary and just add visual noise in my opinion.

`use struct` is easy to parse but with several words it can get tricky. I don't know in which directions Rust will evolve but I would like to see it get richer and would like to see it also newbie-friendly thanks to tools. I already happens now with `cargo expand` and `cargo modules` and I would like to see more of it.

> Those look quite nice to me.

And that's awesome! It's only slightly awkward to me, not "absolutely ugly" as was the case with ATS. So I can live with it.

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [December 22, 2022, 2:04pm UTC](https://internals.rust-lang.org/t/improve-use-declarations/17425/13 "2022-12-22T14:04:40Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
