5 ms·
related: https://doc.rust-lang.org/nomicon/vec/vec.html https://doc.rust-lang.org/nomicon/vec/vec.html
by 5- 1y ago
related: https://doc.rust-lang.org/nomicon/vec/vec.html https://doc.rust-lang.org/nomicon/vec/vec.html
- James_K 1y agoOh, I never knew that Rust had variance. I always just assumed everything was invariant. Strange that they've got no way to write it down in the type system.
- tialaramex 1y agohttps://doc.rust-lang.org/reference/subtyping.html#variance https://doc.rust-lang.org/reference/subtyping.html#variance Lifetimes imply the need for the idea of variance.
- kibwen 1y agoRather, any language with both generics and subtyping needs to consider variance, and Rust doesn't have subtyping in general, but lifetimes do technically have subtyping relationships, so lifetimes are the only place where this matters, and fortunately Rust can just infer the right behavior based on some simple type-level heuristics.
- James_K 1y agoUnfortunately, more like. I'd much rather have some explicit syntax for it that potentially never realise it's a feature. I was baffled beyond belief the first time the compiler asked me to put a ghost in my struct.
- pornel 1y agoIn prehistoric Rust, variance used to be named more explicitly. However, the terminology of covariant and contravariant subtyping of lifetimes is a language theory jargon. This is the right perspective for language design, but programmers using the language don't necessarily use these terms. It's been replaced with a "by example" approach. It's much easier to teach it: just add a fake field that acts if you had this type in your struct. Rust then figures out all of the details it needs.
- lyu07282 1y ago> but programmers using the language don't necessarily use these terms. this always annoyed me about the python type annotations, you are supposed to already know what contravariant / covariant / invariant means, like: `typing.TypeVar(name, covariant=False, contravariant=False, infer_variance=False)` Its used in documentation and error messages too: > the SendType of Generator behaves contravariantly, not covariantly or invariantly. https://docs.python.org/3/library/typing.html#annotating-generators-and-coroutines https://docs.python.org/3/library/typing.html#annotating-gen...
- kibwen 1y agoVariance is an absolute disaster when it comes to language pedagogy. One of the smartest things Rust ever did was avoiding mentioning it in the surface-level syntax.
- branko_d 1y agoWhy? It's just a property of type transformation. Assuming Parent <- Child ("<-" denotes inheritance): - If Generic<Parent> <- Generic<Child>: it's covariant. - If Generic<Parent> -> Generic<Child>: it's contravariant. - Otherwise: it's invariant. Or at least it's that straightforward in C#. Are there complications in Rust?
- tialaramex 1y agoSure, you can keep telling me that and it doesn't stay. I'm completely happy writing Rust, and I am aware it needs variance to work in principle and when I do need that information I know the magic words to type into doc search. It's like how I can hold in my head how classical DH KEX works and I can write a toy version with numbers that are too small - but for the actual KEX we use today, which is Elliptic Curve DH I'm like "Well, basically it's the same idea but the curves hurt my head so I just paste in somebody else's implementation" even in a toy. Sorry?
- dwattttt 1y ago
- bobbylarrybobby 1y agoAside from better documentation (it would be quite nice if rustdoc automatically showed the computed variance for types where it mattered), what would writing it down in the type system get you? Separately, if everything were invariant, you wouldn't be able to use a `&'static T` where a `&'non_static T` was expected, which would be quite unpleasant!