Rust Traits vs C++ Concepts

preview_player
Показать описание
Rust and C++ have huge overlap in their design and user bases. There are no shortage of parallels between the language - some language features are very similar and comparisons can be very useful, some might seem similar at first, but have subtle differences, and other language ideas might be different entirely even if they are share use cases!

So where do C++ concepts and Rust traits fit on that scale? They're both language features used to express functionality which a given type implements, but how much further do the parallels go? Here Alex introduces the two, discussing their differences, with lots of time for broader discussion at the end.

Presenter(s): Alex

Meetup info:
You can also find us on discord, drop us a message to be sent the link.

Big thank you to Esri for sponsoring our meetup page
Рекомендации по теме
Комментарии
Автор

U gys r crazy, Amazing rust content !! Thanks a ton.
Lately found this fabulous treasure in YouTube.

bjugdbjk
Автор

Glad to see more people talking about Rust :)

haystackdmilith
Автор

Exactly what I needed and was looking for! Thanks!!

arshsohi
Автор

So "concepts" seem kinda like Go interfaces: you automatically implement them if your type conforms to the spec. Interesting.

JamesBlacklock
Автор

So concepts are kind of like Duck Typing?

alienmsehunter
Автор

19:30 we need these anonymous interfaces in rust. It's annoying when you have shared behavior outside your crate and the author didn't define and implement traits. Maybe introduce a keyword that makes a trait bound loose and only looks if the trait could be implemented with an empty impl block.

redcrafterlppa
Автор

I think C++s concepts have, on a theoretical level, a few advantages and a few disadvantages compared to traits. But on a practical level they will sadly probably never be as powerful as Rusts traits.

There are a few things you didn't entirely follow up on, that empower Rusts traits over C++ concepts.

One of them is its interaction with virtual dispatch, which I would consider fairly brilliant. C++ has all these confusing rules about virtual functions and virtual Inheritance and the static variants (which can interact strangely). In Rust meanwhile you simply don't differentiate at definition (since you don't have Inheritance), and only the usage determines which variant gets used. Meanwhile elsewhere you get the performance of static dispatch (and the optimizations that allows).

In other areas they trade blows. For example, you can implement one of your Rust traits for any foreign type. Which you cannot for C++, with C++ you cannot add methods to classes, and you may not have access to everything inside to supplant the methods you would need (not to speak of the complication it would cause to have to handle multiple cases, certainly not helping with compiler errors). But, on the other hand, you what you cannot do with Rust is implement foreign traits for foreign types (ish, there are exceptions), because of coherence rules (in that situation also known as the orphan rules). That is trivial with C++, any type that conforms to the concept is accepted. But that also means false positives that may lead to weird behavior, eg. when a "start" method exists but doesn't do what you expected. Rusts traits are Nominal (though without Inheritance as a base for Polymorphism, but instead ad-hoc adoption with rules for coherence like the ones mentioned above), while C++s concepts are more akin to structural typing.

While we're on that topic, another thing that trait coherence kindof ruins (for now at least, there are efforts that would help) is that generic implementation of traits you mentioned ("conditional method implementation"). But first a bit of a foundation: As you said, Trait1 + Trait2 is an AND requirement. OR would not make sense in most casss if you think about it: All you know about the generic T is that it implements these trait bounds, and most of the time you would want to use the methods provided by these bounds, having then connected by OR means you can't use either of the methods. As you correctly stated, the way to do OR would be to have 2 seperate implementations. But now we get to the issue: What do you do if a type implements both Trait1 and Trait2? You have 2 different implementations. I'm not certain right now where Rust will complain about that right now, but in any case it's not... Nice.

You would have to "prefer" one of these implementations above the other one. One way to archive that is with "Negative Trait implementations", which you could add to the trait bounds, and exclude types that implement said traits. But they are not yet available to people without using nightly. They've been that way for long, not sure why actually, gotta look up what's stopping them from being stabilized.


But yeah, in sum, it can be said that C++ concepts and Rust traits have advantages and disadvantages over each other. And C++ would not have been avow to adopt a system akin to Rusts traits retroactively anyways. But crucially, as you stated, C++ hasn't exactly been quick at adopting them anyways, with even many COMPILERS not supporting then yet, and as long as that's a thing there's going to be very little of the rest of the ecosystem using them, as you can't rely on them being present. Even of these issues would be solved at some point, given the past experiences with other features, most APIs still won't adopt being based on Concepts.

SMTM
Автор

Anyone who claims C++ concepts are copying Rust traits has serious brain damage - concepts for C++ have been in development for more than 20 years, before Rust was even an idea.

rinket