Because it can also be called with any class that doesn't have the bar method, and good luck deciphering the compiler error for it when it's nested 3 levels deep into some far corner of the STL.
While I've never really found much practical use for mixins, it is fairly easy to create a runtime system for them in Java. Any interface can become a mixin simply by storing state in a static global hashmap with `this` as the key to the map. Specifically for the map, I would use `Collections.synchronizedMap(new WeakHashMap<>())` so that the map is thread-safe and allows mixin instances to be garbage collected.
It actually does have specific applications. That Wikipedia article shows a good example of polymorphic method chaining. In a former life, I worked with Microsoft’s Active Template Library, which is entirely based on this pattern.
Code with types on the right like this makes me very sad
static
auto create(const char* data) -> Result<String>
Types are a lot more ergonomic on the left - the return type of a function and the type of a variable are very important for understanding and skimming code. When the return type is on the right, it is physically very far from the name of the object and I have to scan the entire line with my eyes to get the same amount of information I would get by just looking at the left column and scrolling down if it were on the left. I am pretty sure in another 20 years types on the right will be regarded as one of the ergonomic fails of current language design. At least, if have to do this, put the type right under the object name, like so:
static auto
create(const char* data)
-> Result<String>
Types are only nicer on the left when it isn't also annotated with all the other static constexpr [[nodiscard]] nonsense. And left types are actually greppable seperately from variable declarations.
Having both left and right types is stupid, but as a whole right types are easier to deal with
I learned of a cute side effect when one puts the function name on its own line, like above.
In BSD of yore and modern contemporaries, one could often perform `grep '^function'` and end up finding the source file quite easily. I think it also makes using ctags(1) a bit easier too, but not entirely sure on that bit.
> I think the big asterick to all of this design is that my ideal framework would not look like standard C++ but like a slightly weirder Rust stdlib
An interesting option in this space is rpp [1], which bills itself as a “Minimal Rust-inspired C++20 STL replacement”
[1]: https://github.com/TheNumbat/rpp
That `String` leaks memory, it doesn't have a destructor.
> That `String` leaks memory, [...]
So does the clone...
I don't really see the point when C++ already lets you write
void foo(auto& t) { t.bar(); }
which can be called with any class that has the .bar() method anyway.
Because it can also be called with any class that doesn't have the bar method, and good luck deciphering the compiler error for it when it's nested 3 levels deep into some far corner of the STL.
That is what concepts fix. It lets you enforce at build time that `t` does have member `.bar()`.
While I've never really found much practical use for mixins, it is fairly easy to create a runtime system for them in Java. Any interface can become a mixin simply by storing state in a static global hashmap with `this` as the key to the map. Specifically for the map, I would use `Collections.synchronizedMap(new WeakHashMap<>())` so that the map is thread-safe and allows mixin instances to be garbage collected.
It seems messy and even the author of TFA is unconvinced.
How does a mixin compare to role or interface in languages that do not have multiple inheritance?
We've used this pattern for years. It definitely delivers in terms of being lower overhead. I will say that compiler errors can be nonsense though.
In a language with ad-hoc polymorphism like C++, mixins seems entirely unnecessary.
You can just declare by convention that a freestanding clone(T x) -> T function should exist for it to be 'cloneable'.
This “mixin” concept uses the CRTP pattern, as mentioned in the post: https://en.wikipedia.org/wiki/Curiously_recurring_template_p...
It actually does have specific applications. That Wikipedia article shows a good example of polymorphic method chaining. In a former life, I worked with Microsoft’s Active Template Library, which is entirely based on this pattern.
And just use concepts and call it a day.
Code with types on the right like this makes me very sad
Types are a lot more ergonomic on the left - the return type of a function and the type of a variable are very important for understanding and skimming code. When the return type is on the right, it is physically very far from the name of the object and I have to scan the entire line with my eyes to get the same amount of information I would get by just looking at the left column and scrolling down if it were on the left. I am pretty sure in another 20 years types on the right will be regarded as one of the ergonomic fails of current language design. At least, if have to do this, put the type right under the object name, like so: Future readers will thank you.Types are only nicer on the left when it isn't also annotated with all the other static constexpr [[nodiscard]] nonsense. And left types are actually greppable seperately from variable declarations.
Having both left and right types is stupid, but as a whole right types are easier to deal with
I learned of a cute side effect when one puts the function name on its own line, like above.
In BSD of yore and modern contemporaries, one could often perform `grep '^function'` and end up finding the source file quite easily. I think it also makes using ctags(1) a bit easier too, but not entirely sure on that bit.
I cannot disagree more strongly. Putting the name of the function (or method) in the middle of the declaration drastically lowers readability.
C-style type declarations were always the most painful part of reading C.
No they won't. Your example is way more unpleasant to read.