4 ms·
This is pretty much how every language does generics except C++, so it's not actually an issue with Rust.
by infinity0 11y ago
This is pretty much how every language does generics except C++, so it's not actually an issue with Rust.
- dbeck74 11y agoI don't think it is an issue either. In fact I was pretty happy when I understood the concept. Unfortunately I haven't got experience with generics in languages other than C++, so thanks for pointing this out.
- mmebane 11y agoI've often thought of C++'s templates (when used in the "straightforward" manner, anyway) as more of compile-time duck typing than a real generic type system. Even moving from C++ to Java took a while to get used to.
- scott_s 11y agoMoving to Java generics took me a while mostly because of type erasure. In C++, I'm used to being able to use the type in a generic class or function, which kept biting me in Java.
- masklinn 11y agoWhat do you mean by use the type? Query for type metadata at runtime?
- deleted 11y ago[deleted]
- scott_s 11y agoNo, that's not what I meant, but yes, that is a limitation. (Just not one I hit.) The big one is not being able to allocate objects of that type. For example, in C++, I can say: template <class T> T* allocate() { return new T(); } That's not possible in Java because of type erasure. When you try something like that, you get an error message like: Erasure.java:12: error: unexpected type return new T(); ^ required: class found: type parameter T where T is a type-variable: T extends Object declared in class Foo Again, this is because of type erasure: Foo<T> is really Foo<Object>, where Java just does a cast for you to T in all of the right places. It does not actually know the type. For me, that lead to all sort of contortions because a class Foo<T> could not allocate objects of type T internally. I needed to create factory methods in other places which Foo would call. In the instance I'm thinking of, those factory methods ended up living in derived classes. C++ templates have its issues, but it allows parametric polymorphism. In Java, I could not write such code, which was what I was used to. Because of type erasure, I was forced more towards subtype polymorphism, even though I was implementing generic classes.
- masklinn 11y agoI'm not quite sure that's due to type erasure. What would happen to this code if T were an interface? Meanwhile even though (AFAIK) GHC uses type erasure, you can do something like that and create values "de novo" if the typeclass supports it e.g. Alternative's `empty` or MonadPlus's `mzero`
- mmebane 11y agoEven if you constrain the type to be something you know is a class, it won't work. [1] The typical workaround in Java is to either pass around .class instances, or to do tricks with anonymous subclasses to create a type token. [2] [1]: https://ideone.com/th18eh https://ideone.com/th18eh [2]: http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/reflect/TypeToken.html http://docs.guava-libraries.googlecode.com/git/javadoc/com/g...
- masklinn 11y ago> Even if you constrain the type to be something you know is a class, it won't work. [1] Oh yes, I'm not saying it's possible to do this in Java, AFAIK you're right that it's not, I'm saying I'm not sure it's because of type erasure, at least type erasure on its own.
- scott_s 11y agoI think it is. As far as Java is concerned, T is Object in that context. It can't generate code for "allocate a T" because Foo only actually operates on Objects, not Ts. That is, there will be one version of Foo, and that version will generate code to interact with Objects, not Ts. It can't allocate a T because the type of T is erased from Foo. That is type erasure.