# Proposal: Change terminology from "trait object" to "dynamic trait"

**URL:** https://internals.rust-lang.org/t/proposal-change-terminology-from-trait-object-to-dynamic-trait/7091
**Category:** language design
**Created:** [March 20, 2018, 7:53pm UTC](https://internals.rust-lang.org/t/proposal-change-terminology-from-trait-object-to-dynamic-trait/7091 "2018-03-20T19:53:15Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![nikomatsakis](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nikomatsakis/32/5410_2.png) [@nikomatsakis](https://internals.rust-lang.org/u/nikomatsakis)
#### Post date: [March 20, 2018, 7:53pm UTC](https://internals.rust-lang.org/t/proposal-change-terminology-from-trait-object-to-dynamic-trait/7091/1 "2018-03-20T19:53:15Z")

</div>

Given the pending stabilization of the new `dyn Trait` syntax, I think it’s time that we shift our terminology. I think we should start calling `dyn Trait` types **dynamic trait types**. Moreover, we should deprecate the term “object safe trait” and say “dyn-capable trait”. These changes have a few advantages:

- It is relatively obvious from the syntax and helps explain what `dyn` stands for.
- The existing “trait object” term feels suboptimal to me; it may confuse people into expecting something more OOP-like than they are getting. And anyway the “object”, in some sense, is the _box_ more than the `dyn Trait` itself (that is, the `Box<dyn Trait>` type in its entirety is really the _object_).
- “dyn-capable” just seems a lot more obvious to me than “object safe” – it expresses the idea that traits which accept some restrictions can be used in additional ways. It doesn’t confuse with memory safety or other forms of safety.

---

<div class="post-metadata">

### Author: ![nikomatsakis](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nikomatsakis/32/5410_2.png) [@nikomatsakis](https://internals.rust-lang.org/u/nikomatsakis)
#### Post date: [March 20, 2018, 7:55pm UTC](https://internals.rust-lang.org/t/proposal-change-terminology-from-trait-object-to-dynamic-trait/7091/2 "2018-03-20T19:55:28Z")

</div>

Going further: I would like to have an attribute that declares a trait to be dyn-capable. Something like:

```rust
#[dyn_capable]
trait Foo { ... }

```

It would then be a compilation error if that is not the case. We would lint (warn) if you do `dyn Foo` and `Foo` is not declared as `dyn_capable`.

The purpose of `dyn_capable` is then to declare your intention that `Foo` should be usable as an object, which implies accepting limitations on its design.

---

<div class="post-metadata">

### Author: ![Centril](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/centril/32/3334_2.png) [@Centril](https://internals.rust-lang.org/u/Centril)
#### Post date: [March 20, 2018, 8:13pm UTC](https://internals.rust-lang.org/t/proposal-change-terminology-from-trait-object-to-dynamic-trait/7091/3 "2018-03-20T20:13:41Z")

</div>

> [@nikomatsakis](#):
>
> I think we should start calling dyn Trait types dynamic trait types.

This feels like a good change 👍

> [@nikomatsakis](#):
>
> And anyway the “object”, in some sense, is the box more than the dyn Trait itself (that is, the Box\<dyn Trait\> type in its entirety is really the object).

We need some way to refer to `Box<dyn Foo>` tho -- personally, I'd call it a "boxed dynamic existential Foo" but "boxed dynamic Foo" works and is shorter.

## On `#[dyn_capable]`

This also sounds like a great idea 👍

For reference, (which I'm sure you're aware of), the current way to do:

```rust
#[dyn_capable]
trait Foo { ... }

```

is:

```rust
trait Foo { ... }
fn assert_object_safe_foo(_: &Foo) {}

```

But the current method has the drawback of not being in the documentation, which `#[dyn_capable]` could / would be.

A different way to do `#[dyn_capable]` would be via "ConstraintKinds" and `auto meta traits`:

```rust
#[lang_item = "dyn"]
auto meta trait dyn {}

trait Foo {}
// This will be inferred automatically, but we can explicitly state it:
meta impl dyn for Foo {}
// ^-- This will be shown in documentation, and we can lint as well.

// General assertion that a trait is dyn capable:
fn assert_dyn_capable<trait C: dyn>();

#[test]
fn foo_dyn_capable() {
    assert_dyn_capable::<Foo>();
}

```

This however requires ConstraintKinds which we are **far away** from having. We can also desugar `#[dyn_capable]` into `meta impl dyn for Foo {}` at a later stage if need be, so the `#[dyn_capable]` proposal is forward compatible with this idea.

---

<div class="post-metadata">

### Author: ![nikomatsakis](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nikomatsakis/32/5410_2.png) [@nikomatsakis](https://internals.rust-lang.org/u/nikomatsakis)
#### Post date: [March 20, 2018, 8:16pm UTC](https://internals.rust-lang.org/t/proposal-change-terminology-from-trait-object-to-dynamic-trait/7091/4 "2018-03-20T20:16:04Z")

</div>

> [@Centril](#):
>
> For reference, (which I’m sure you’re aware of), the current way to do

Yeah, I'm looking for a better alternative. =) I wanted also to have the lint, so that if clients of your library are using your traits in `dyn Form`, they get warnings, which might lead them to open issues on your repo, might might in turn lead you to be aware that they are doing that. =)

Maybe we should actually have:

```rust
#[dyn_capable(no)]

```

as well, which artificially forbids the use of `dyn Trait`.

This way, for backwards compat reasons, `trait Foo` is sort of ambiguous without such a declaration (presuming it uses only dyn-capable features). Eventually, we can slowly migrate the lint to deny-by-default and so forth to "tighten the noose" there.

---

<div class="post-metadata">

### Author: ![Centril](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/centril/32/3334_2.png) [@Centril](https://internals.rust-lang.org/u/Centril)
#### Post date: [March 20, 2018, 8:20pm UTC](https://internals.rust-lang.org/t/proposal-change-terminology-from-trait-object-to-dynamic-trait/7091/5 "2018-03-20T20:20:43Z")

</div>

> [@nikomatsakis](#):
>
> I wanted also to have the lint, so that if clients of your library are using your traits in dyn Form, they get warnings, which might lead them to open issues on your repo, might might in turn lead you to be aware that they are doing that. =)

A worthwhile goal 👍

On:

```rust
#[dyn_capable(no)]

```

I think that is even better.

```rust
#[dyn_capable(no)]

// As well as:

#[dyn_capable(yes)]
// or equivalently:
#[dyn_capable]

```

I really like the documenting + executable nature of this.

---

<div class="post-metadata">

### Author: ![Keats](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/keats/32/1715_2.png) [@Keats](https://internals.rust-lang.org/u/Keats)
#### Post date: [March 20, 2018, 9:09pm UTC](https://internals.rust-lang.org/t/proposal-change-terminology-from-trait-object-to-dynamic-trait/7091/6 "2018-03-20T21:09:39Z")

</div>

Might as well use `true`/`false` rather than `yes`/`no`? Or:

```rust
#[dyn_capable = true]
#[dyn_capable = false]
#[dyn_capable]

```

So you get the syntax highlighting at the same time (once attr literals are stable).

---

<div class="post-metadata">

### Author: ![leodasvacas](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/leodasvacas/32/4060_2.png) [@leodasvacas](https://internals.rust-lang.org/u/leodasvacas)
#### Post date: [March 20, 2018, 10:14pm UTC](https://internals.rust-lang.org/t/proposal-change-terminology-from-trait-object-to-dynamic-trait/7091/7 "2018-03-20T22:14:39Z")

</div>

> [@nikomatsakis](#):
>
> dynamic trait types

I like how "trait object" sounds like something you make from a trait, while "dynamic trait" sounds like a property of the trait, but that's confusing since the property is being dyn-capable. How about "trait dyn type" instead? It avoids putting an adjective before "trait" and the abbreviation evokes the syntax.

---

<div class="post-metadata">

### Author: ![withoutboats](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/withoutboats/32/4560_2.png) [@withoutboats](https://internals.rust-lang.org/u/withoutboats)
#### Post date: [March 20, 2018, 10:17pm UTC](https://internals.rust-lang.org/t/proposal-change-terminology-from-trait-object-to-dynamic-trait/7091/8 "2018-03-20T22:17:05Z")

</div>

I don't like dyn capable (seems supe jargony to me) but I like ""dynamic trait," maybe its more of a "dynamic type" though, or a "dynamic trait type."

> [@nikomatsakis](#):
>
> Eventually, we can slowly migrate the lint to deny-by-default and so forth to “tighten the noose” there.

If we're going to require this on every trait, or even every public trait - and I don't think we should - I wouldn't want the syntax to be an attribute.

---

<div class="post-metadata">

### Author: ![Centril](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/centril/32/3334_2.png) [@Centril](https://internals.rust-lang.org/u/Centril)
#### Post date: [March 20, 2018, 10:45pm UTC](https://internals.rust-lang.org/t/proposal-change-terminology-from-trait-object-to-dynamic-trait/7091/9 "2018-03-20T22:45:00Z")

</div>

> [@withoutboats](#):
>
> I don’t like dyn capable (seems supe jargony to me) but I like "“dynamic trait,” maybe its more of a “dynamic type” though, or a “dynamic trait type.”

"Dyn capable" just sounds like a shorthand for "Can be used as a dynamic trait type" -- not sure why it sounds like jargon to you..?

> [@withoutboats](#):
>
> If we’re going to require this on every trait, or even every public trait - and I don’t think we should - I wouldn’t want the syntax to be an attribute.

Well... we could do something like:

```rust
// Using as Box<dyn Foo> is legal
dyn trait Foo {}

// Using as Box<dyn Foo> is illegal
trait Foo {}

```

but it feels too heavyweight (and will break a ton of code), especially if (_totally not given_) we're going to introduce meta traits in the future. Therefore, to me, attributes seem like the cheaper solution right now.

If we go with this `dyn trait Foo {}` syntax, it would also be a breaking change, so we would need to sneak it into edition 2018.

---

<div class="post-metadata">

### Author: ![withoutboats](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/withoutboats/32/4560_2.png) [@withoutboats](https://internals.rust-lang.org/u/withoutboats)
#### Post date: [March 20, 2018, 11:08pm UTC](https://internals.rust-lang.org/t/proposal-change-terminology-from-trait-object-to-dynamic-trait/7091/10 "2018-03-20T23:08:58Z")

</div>

> [@Centril](#):
>
> “Dyn capable” just sounds like a shorthand for “Can be used as a dynamic trait type” – not sure why it sounds like jargon to you…?

"Dyn" is short-hand and "X capable" is not really an adjective phrase that I can think of another example of. With "object-safe" at least I have "type-safe" and "memory-safe" to compare it to, which makes it feel less like a technical term I need to memorize. "Capable" is also less of a casual word than "safe."

---

<div class="post-metadata">

### Author: ![Centril](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/centril/32/3334_2.png) [@Centril](https://internals.rust-lang.org/u/Centril)
#### Post date: [March 20, 2018, 11:28pm UTC](https://internals.rust-lang.org/t/proposal-change-terminology-from-trait-object-to-dynamic-trait/7091/11 "2018-03-20T23:28:11Z")

</div>

Brainstorming… How about:

- “dyn-safe” instead? `#[dyn_trait_safe]` or `#[dyn_safe]`
- `#[erasable]` (type erasure)

If we stick with “object safe” we could do `#[object_safe]`.

---

<div class="post-metadata">

### Author: ![Centril](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/centril/32/3334_2.png) [@Centril](https://internals.rust-lang.org/u/Centril)
#### Post date: [March 20, 2018, 11:38pm UTC](https://internals.rust-lang.org/t/proposal-change-terminology-from-trait-object-to-dynamic-trait/7091/12 "2018-03-20T23:38:59Z")

</div>

More brainstorming:

1. 

```rust
#[dynamic_trait]
trait Foo {}

```

1. 

```rust
#[dynamic]
trait Foo {}

```

1. 

```rust
#[dyn]
trait Foo {}

```

An argument in favor of attributes is that you don’t have to think about the order between `dyn` and `unsafe` (and possibly `const`) when defining the trait.

---

<div class="post-metadata">

### Author: ![nikomatsakis](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nikomatsakis/32/5410_2.png) [@nikomatsakis](https://internals.rust-lang.org/u/nikomatsakis)
#### Post date: [March 21, 2018, 9:51am UTC](https://internals.rust-lang.org/t/proposal-change-terminology-from-trait-object-to-dynamic-trait/7091/13 "2018-03-21T09:51:57Z")

</div>

> [@withoutboats](#):
>
> I don’t like dyn capable (seems supe jargony to me)

I hear you -- open to alternatives.

> [@withoutboats](#):
>
> “dynamic trait type.”

I believe this is what I wrote:

> I think we should start calling dyn Trait types **dynamic trait types**.

> [@withoutboats](#):
>
> If we’re going to require this on every trait, or even every public trait - and I don’t think we should - I wouldn’t want the syntax to be an attribute.

I did not mean to imply it would be required on every trait. But what I was thinking is that any trait that you use with `dyn` would want to be marked `#[dyn_capable]`, so that you know you are using it in the expected way.

I'm not sure how important it is though. I'd be happy to just start with having a way to "opt-in" to those checks. (And not necessarily connect it to _uses_ of `dyn`.)

(Why wouldn't you want it to be an attribute? Attribute feels right to me.)

---

<div class="post-metadata">

### Author: ![nikomatsakis](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nikomatsakis/32/5410_2.png) [@nikomatsakis](https://internals.rust-lang.org/u/nikomatsakis)
#### Post date: [March 21, 2018, 9:53am UTC](https://internals.rust-lang.org/t/proposal-change-terminology-from-trait-object-to-dynamic-trait/7091/14 "2018-03-21T09:53:06Z")

</div>

> [@nikomatsakis](#):
>
> Attribute feels right to me

To elaborate: it doesn't affect the meaning of the trait items. It just imposes some restrictions on the trait's future trajectory.

I am not keen on `dyn trait Foo` because it makes it feel (to me) like the trait is "inherently dynamic" or something, or _limited_ to dynamic trait types.

---

<div class="post-metadata">

### Author: ![nikomatsakis](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nikomatsakis/32/5410_2.png) [@nikomatsakis](https://internals.rust-lang.org/u/nikomatsakis)
#### Post date: [March 21, 2018, 9:56am UTC](https://internals.rust-lang.org/t/proposal-change-terminology-from-trait-object-to-dynamic-trait/7091/15 "2018-03-21T09:56:24Z")

</div>

> [@Centril](#):
>
> An argument in favor of attributes is that you don’t have to think about the order between dyn and unsafe (and possibly const) when defining the trait.

See, `unsafe trait` feels different -- it is something that implementors of the trait must be aware of (since they need an `unsafe impl`).

Similarly, `const trait` -- if we supported that -- would presumably mean that implementors must have a `const impl` (or all `const fn`, etc).

But `dyn trait` doesn't have that character. It is just about the trait _definition_ (implementors can do whatever).

---

<div class="post-metadata">

### Author: ![withoutboats](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/withoutboats/32/4560_2.png) [@withoutboats](https://internals.rust-lang.org/u/withoutboats)
#### Post date: [March 21, 2018, 10:07am UTC](https://internals.rust-lang.org/t/proposal-change-terminology-from-trait-object-to-dynamic-trait/7091/16 "2018-03-21T10:07:36Z")

</div>

> [@nikomatsakis](#):
>
> I did not mean to imply it would be required on every trait. But what I was thinking is that any trait that you use with dyn would want to be marked #[dyn\_capable], so that you know you are using it in the expected way.

That sonunds fine (though I think it should be very optional, analogous to an allow by default lint for example). But when you have dyn\_capable(no) it sounds like dividing the world into two sets, one which can be used as objects and one which can't. That would mean it'd be idiomatic to put this on every trait you define ("to avoid the back compat hazard!"), at which point it shouldn't be an attribute.

---

<div class="post-metadata">

### Author: ![nikomatsakis](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nikomatsakis/32/5410_2.png) [@nikomatsakis](https://internals.rust-lang.org/u/nikomatsakis)
#### Post date: [March 21, 2018, 10:28am UTC](https://internals.rust-lang.org/t/proposal-change-terminology-from-trait-object-to-dynamic-trait/7091/17 "2018-03-21T10:28:46Z")

</div>

> [@withoutboats](#):
>
> That sonunds fine (though I think it should be very optional, analogous to an allow by default lint for example). But when you have dyn\_capable(no) it sounds like dividing the world into two sets, one which can be used as objects and one which can’t.

My goal with `#[dyn_capable(no)]` was to allow you to _opt-out_ from being dyn-capable -- even if you otherwise would be -- because you expect to maybe change the trait in incompatible ways in the future, e.g. by adding default fns that are generic or something. But maybe that's not necessary.

---

<div class="post-metadata">

### Author: ![kornel](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kornel/32/2711_2.png) [@kornel](https://internals.rust-lang.org/u/kornel)
#### Post date: [March 21, 2018, 10:45am UTC](https://internals.rust-lang.org/t/proposal-change-terminology-from-trait-object-to-dynamic-trait/7091/18 "2018-03-21T10:45:41Z")

</div>

+1 for name change.

`dyn trait Foo {}` seems OK. Or `impl dyn for Foo; impl !dyn for Foo;`

I’m not a fan of `#[]` syntax, which seems to be reserved for things that are complex or “oops, we forgot to reserve a keyword for this” escape hatch.

---

<div class="post-metadata">

### Author: ![Centril](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/centril/32/3334_2.png) [@Centril](https://internals.rust-lang.org/u/Centril)
#### Post date: [March 21, 2018, 10:56am UTC](https://internals.rust-lang.org/t/proposal-change-terminology-from-trait-object-to-dynamic-trait/7091/19 "2018-03-21T10:56:17Z")

</div>

> [@nikomatsakis](#):
>
> But dyn trait doesn’t have that character. It is just about the trait definition (implementors can do whatever).

This is a compelling argument; `unsafe` and `const` have the character of being effects (or restrictions thereof) which `dyn` is not. Instead, `dyn` has an entirely different "category" -- traits of traits (meta traits).

> [@kornel](#):
>
> I’m not a fan of # syntax, which seems to be reserved for things that are complex or “oops, we forgot to reserve a keyword for this” escape hatch.

It can often be that reason, yes; but in this case, I think `dyn trait Foo {}` is misleading for the reason @nikomatsakis voiced: that it makes the trait feel inherently dynamic (or limited to being dynamic).

---

<div class="post-metadata">

### Author: ![Ixrec](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/ixrec/32/6754_2.png) [@Ixrec](https://internals.rust-lang.org/u/Ixrec)
#### Post date: [March 21, 2018, 9:00pm UTC](https://internals.rust-lang.org/t/proposal-change-terminology-from-trait-object-to-dynamic-trait/7091/20 "2018-03-21T21:00:49Z")

</div>

I also dislike “dynamic trait” because that makes it sound like it’s a property of the trait, not a runtime polymorphic fat pointer to some type implementing that trait. In fact the whole point of adding `dyn` in front of the trait is to make it clear when we’re talking about the trait itself and when we’re talking about some _thing_ that implements the interface defined by the trait. Calling the _thing_ an “[adjective] trait” feels like re-encouraging the exact confusion that we just made this high-churn change to combat.

Unfortunately, I really have no idea what to call the thing other than a “trait object”. Part of me wants to say `&dyn Trait` is a “polymorphic reference”, but that doesn’t provide a name for the unsized `dyn Trait` type, and I don’t know how many people would assume “polymorphic” implies runtime polymorphic the way I do. “dynamic reference” sounds like the reference might sporadically change what it refers to, which is not at all what we want. “dynamic type” is… maybe okay? I have no idea how people would interpret that phrase. And any other term that doesn’t contain the word “dynamic” will probably be no better than “trait object”.

[Next page](https://internals.rust-lang.org/t/proposal-change-terminology-from-trait-object-to-dynamic-trait/7091.md?page=2)
