6 ms·
>- allows traits to be implemented for existing types, as opposed > to C++ where the type's declaration has to list all base classes. >- allows a type
by detrino 11y ago
>- allows traits to be implemented for existing types, as opposed
> to C++ where the type's declaration has to list all base classes.
>- allows a type to be used through dynamic dispatch while allowing users
> who don't need this to avoid the vtable overhead.
In C++ you can have this as well. For example, std::function is able to wrap any callable type without them having to have any base classes. Sean Parent gives a great talk about this: http://channel9.msdn.com/Events/GoingNative/2013/Inheritance-Is-The-Base-Class-of-Evil http://channel9.msdn.com/Events/GoingNative/2013/Inheritance...
- humanrebar 11y agoC++ is Turing-complete, so you can do whatever you want. What Rust offers is an hierarchy free (i.e., no inheritance) polymorphism mechanism as a core part of the language.
- detrino 11y agoThe turing-complete argument makes no sense here.
- humanrebar 11y agoSure it does. I can pass around a struct containing any bytes I want and do anything I want with it. If I want to define FatPointer that contains an opaque pointer (or some equivalent union) and a polymorphic Strategy object of some sort, I can. You can do the same in C, for that matter. Or in assembly. The reason we still come up with new languages is so that you can write code that conforms to certain patterns easily.
- jahewson 11y agoThat has nothing to do with Turing-completeness. There are Turing-complete languages which don't even have pointers.
- geofft 11y agoNo, Turing-completeness does not mean you can "do whatever you want". It means you can compute whatever you want that is computable. If the way you want to compute things is to embed a Rust compiler, yes you can do that, but there are many things that we'd colloquially refer to as "do whatever you want" that apply to the semantics of C++ itself. You cannot, for instance, create a new abstract base class and have a pre-existing class in someone else's header implement your abstract base class, such that a pointer to that pre-existing class can be dynamic_cast to your class. Because that statement refers to C++ semantics, not your ability to compute things, it's not affected by the claim of Turing-completeness.
- humanrebar 11y ago> You cannot, for instance, create a new abstract base class and have a pre-existing class in someone else's header implement your abstract base class, such that a pointer to that pre-existing class can be dynamic_cast to your class. Sure you can, for some value of base class and cast. You might not be able to use particular keywords, but data is data and math is math. You might not be able to use the built-in type system to do it. C and javascript programmers write their own inheritance-based type systems all the time. And anything you can do in C, you can do in C++ if you really want to.
- marrs 11y agoJS is a bad example because people who do that are preferring inheritance to composition, which is absurd. In the case of C, yes you can do that, and where performance is critical you might prefer to do it, but it's obviously not going to be your first choice if you have any sense.
- eli_gottlieb 11y agoI think he means that, through templates, the C++ type system is Turing-complete.
- steveklabnik 11y agoRust's is too.
- kibwen 11y agoThough the skimpy recursion limit makes it fairly impossible to do anything interesting with this property, much to the chagrin of some people. :P
- comex 11y agoThis only works for callables, though; if you want a virtual dispatch wrapper for some other set of methods, you have to write it yourself (right?). On the other hand, if you do have a relevant base class and you know the exact type, you can avoid virtual calls in C++ just by declaring the relevant methods final, although the vtable pointer will still bloat the struct a bit. However, I'd say Rust traits are more elegant in unifying what are two separate worlds in C++: (1) calling virtual methods on a base class pointer, which can be (usually is) dispatched at runtime, but thus can't support methods with generic parameters or having a 'virtual type' (instead of a method), and (2) accessing members of template parameter classes, including (possibly generic) methods, constants, typedefs, etc. - much more flexible, but doesn't work at runtime. Also dynamically typed, for better or worse; Rust thinks worse. In Rust, (1) is a trait object, and (2) can be done with a generic parameter specified to implement a certain trait with methods, associated types, and constants. Rust's compiler doesn't try to be magic (unlike, say, Haskell), and so traits with generic methods and such can't be made into trait objects, but they're still traits - they feel like the same basic kind of thing.
- deleted 11y ago[deleted]