5 ms·
Is this the same as Rust's traits and trait objects?
by queuebert 5y ago
Is this the same as Rust's traits and trait objects?
- Twisol 5y agoI don't think so. Per the abstract: > All organizational functions carried out by classes can be accomplished in a simple and natural way by object inheritance in classless languages, with no need for special mechanisms. The paper replaces classical inheritance with prototypal inheritance, but it still relies on inheritance -- and more specifically, dynamic dispatch along an inheritance chain built into an object. Rust's trait system is much (much!) closer to Haskell's typeclasses, Scala's traits, and object algebras [0], all of which are essentially based on passing a set of operations on a type separately from that type itself (with various degrees of compile-time optimization and/or type-driven inference). [0] https://www.cs.utexas.edu/~wcook/Drafts/2012/ecoop2012.pdf https://www.cs.utexas.edu/~wcook/Drafts/2012/ecoop2012.pdf Also from the paper: > No special language features need to be added to support traits objects — a traits object is a regular object shared by all instances of the type using normal object inheritance. Since traits objects are regular objects, they may contain assignable data slots which are then shared by all instances of the data type, providing the equivalent of class variables. Under static dispatch (the default), Rust's traits don't have the same recursive runtime chaining behavior. You can declare supertraits, but with static dispatch (the default) the supertrait methods are resolved at compile time anyway. Under dynamic dispatch over "trait objects", I'm not sure about the details, but it would be reasonable to imagine that the "subtrait" contains a pointer for each supertrait. (Rather critically for Rust, trait implementations are defined statically and contain no data.) Trait objects in Rust do separate the instance data from the trait behavior in the same way that the paper suggests. The term "fat pointer" often comes up -- a trait object is a combination of two pointers, one to the instance data and one to the trait implementation for the instance. The paper refers to the trait implementation itself as the "traits object", but it's fair to call that a minor difference. That said, the impl for a trait object can't be manually set or changed at runtime -- at least, not without unsafe arcane magic and some serious assumptions about codegen from rustc -- and Rust knows exactly what methods are available from a trait object statically, so there's no need for an inheritance-style chained dispatch. If you call a method on a trait, I'm pretty sure Rust will produce machine code that just traverses the trait impls directly to the known location of the pointer to the method you want to call. It doesn't have to check "do you know this method? no, do you know this method? no, ..."
- sillysaurusx 5y agoIt's closest in spirit to Steve Yegge's "Universal Design Pattern": http://steve-yegge.blogspot.com/2008/10/universal-design-pattern.html http://steve-yegge.blogspot.com/2008/10/universal-design-pat... Basically, the core data structure is a special kind of dictionary. When you fetch a key, if the dict doesn't have it, it recurses to a list of "parent" dictionaries that you can specify. I don't know Rust's traits / trait objects, but the observation of the paper is that you can break apart your interfaces into a "traits dict". E.g. dog traits would have bark and pant, and would have a parent link to animal traits, which has eat and sleep, which has a parent link to entity traits, which might have position / collision model / etc. This lets you mix and match functionality at runtime, very similar to adding classes to Python's __bases__ list (which I'm quite find of for mixin purposes: https://github.com/shawwn/mtftorch/blob/8b680ab86603a771804494865fa360e7934e229b/mtftorch/_C/__init__.py#L449-L476 https://github.com/shawwn/mtftorch/blob/8b680ab86603a7718044...)
- nerdponx 5y ago> Basically, the core data structure is a special kind of dictionary. When you fetch a key, if the dict doesn't have it, it recurses to a list of "parent" dictionaries that you can specify. Sounds like Lua metatables, as well as Python classes. Also.. what's this Mftorch thing? Your own library?
- Rochus 5y agoNot the same, but there are similarities. The most obvious difference is that Self is a dynamic language whereas Rust is statically typed. In the Rust bibliography (https://rustc-dev-guide.rust-lang.org/appendix/bibliography.html https://rustc-dev-guide.rust-lang.org/appendix/bibliography....) you find a link to http://scg.unibe.ch/archive/papers/Scha03aTraits.pdf http://scg.unibe.ch/archive/papers/Scha03aTraits.pdf which uses Smalltalk and also discusses the difference of their traits approach to Self. I guess they should also have added this reference: http://scg.unibe.ch/archive/papers/Nier05gTraitsCSharp.pdf http://scg.unibe.ch/archive/papers/Nier05gTraitsCSharp.pdf, which demonstrated in 2005 how to add traits to a strictly/statically typed language.
- deleted 5y ago[deleted]