3 ms·
I mean it has polymorphism via v-tables and composition via traits, that's enough object-orientation for me. Inheritance is a core principle of OOP but in pract
by ThePhysicist 2y ago
I mean it has polymorphism via v-tables and composition via traits, that's enough object-orientation for me. Inheritance is a core principle of OOP but in practice most C++ class hierarchies are relatively flat (there are exceptions like Qt, which I think uses inheritance in a good way), in practice most of that can be mimicked with embedding and composition well enough to work. Not sure if you want to call that object-oriented but operating on polymorphous structures that encapsulate their data is pretty close to object orientation (the good parts of OOP, at least). And I'm not a big expert on Rust but I think you can do most of the things we do in C++ with templates using macros.
- galangalalgol 2y agoThe one lagging thing that isn't easy with rust's generics is expressions, and that looks to be getting kicked down the road indefinitely. You can't have Foo<N> * Foo<M> -> Foo<N+M> or similar. That is a useful thing for statically sized math libraries and for performance oriented metaprogramming. The latter can be clumsily handled with macros, but not the former. It is also blocking portable simd from stabilizing, apparently now indefinitely. I still wouldn't pick any other language a new production product, but I find the stalling out on const generic expressions frustrating, as simd and static math libraries are things I use daily.
- LoganDark 2y agoI could go on and on about the limitations of min_const_generics, missing TAIT (type alias impl trait), unstable coroutines/generators, etc. but none of that stuff erases how much of a miracle Rust is as a language. The industry really needed this. It's practically the poster child of memory safety and security-critical industries are picking it up and Ferrocene is pushing it in safety-critical environments as well and it's just. Good. Please. Finally a serious contender against the terrible reign of C and C++.
- duped 2y ago> You can't have Foo<N> * Foo<M> -> Foo<N+M> or similar. You can though, unless I totally misunderstand your syntax use std::{marker::PhantomData, ops::{Add, Mul}}; pub struct Foo<T> { _p: PhantomData<T>, } impl<N, M> Mul<Foo<M>> for Foo<N> where N: Add<M> { type Output = Foo<<N as Add<M>>::Output>; fn mul(self, rhs: Foo<M>) -> Self::Output { todo!() } }
- ynik 2y agoYou misunderstood. N, M are supposed to be integers (const generics); in your example code you've made them types. Also, your `type Output = Foo<<N as Add<M>>::Output>;` just means "multiplication has the same return type as addition". But desired is that multiplying a Foo<4> with a Foo<3> results in a Foo<7>. Rust decided that it's important to not have instantiation-time compiler errors, but this makes computation with const generics complicated: you're not allowed to write Foo<{N+M}> because N+M might overflow, even if it never actually overflows for the generic arguments used in the program.
- quotemstr 2y agoInstantiation time errors unlock so much metaprogramming potential that Rust is going to be forced to allow them sooner or later.
- Ar-Curunir 2y agoI believe this kind of stuff is being worked on.
- duped 2y agoaiui this isn't inherently limited by instantiation-time error messages and is available on nightly today with the generic_const_exprs feature. It's in the pipeline.
- deleted 2y ago[deleted]
- Neywiny 2y agoYou can do it with macros, the problem is A) documentation B) macro abuse It's so much harder to debug things when function calls are secretly macros, and if I didn't have the vscode cpp language server for goto definition, I'd be completely lost. I'd wager that only 5% of the #defines aren't auto generated by occasionally recursive macros. Maybe hyperbole. Makes it really hard to figure out how existing code works.
- lloeki 2y ago> Inheritance is a core principle of OOP Of Simula (& descendants) proto-OOP objects, not as it was envisioned by the one who coined the term. http://userpage.fu-berlin.de/~ram/pub/pub_jf47ht81Ht/doc_kay_oop_en http://userpage.fu-berlin.de/~ram/pub/pub_jf47ht81Ht/doc_kay... > I didn't like the way Simula I or Simula 67 did inheritance (though I thought Nygaard and Dahl were just tremendous thinkers and designers). So I decided to leave out inheritance as a built-in feature until I understood it better. > OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things. It can be done in Smalltalk and in LISP. Fun that this was mentioned too: >> it uses Haskell-style generics > polymorphism via v-tables and composition via traits, that's enough object-orientation for me For which Alan Kay had this to say: > My math background made me realize that each object could have several algebras associated with it, and there could be families of these, and that these would be very very useful. The term "polymorphism" was imposed much later (I think by Peter Wegner) and it isn't quite valid, since it really comes from the nomenclature of functions, and I wanted quite a bit more than functions. I made up a term "genericity" for dealing with generic behaviors in a quasi-algebraic form. In a way it's fascinating to see how C++ has shaped (dare I say warped) the collective vision of how to do OOP. For example, as a Rubyist, which was heavily influenced by Smalltalk, it is fascinating how hard it can be to explain how fundamentally different message vs call are, and what's the whole point of modules, mostly because the other viewpoint is so warped as to cognitively reject that it can be any different from the C++ model.